return mbox;
}
-static int allegro_mbox_write(struct allegro_dev *dev,
- struct allegro_mbox *mbox, void *src, size_t size)
+static int allegro_mbox_write(struct allegro_mbox *mbox,
+ const u32 *src, size_t size)
{
- struct mcu_msg_header *header = src;
+ struct regmap *sram = mbox->dev->sram;
unsigned int tail;
size_t size_no_wrap;
int err = 0;
+ int stride = regmap_get_reg_stride(sram);
if (!src)
return -EINVAL;
- if (size > mbox->size) {
- v4l2_err(&dev->v4l2_dev,
- "message (%zu bytes) too large for mailbox (%zu bytes)\n",
- size, mbox->size);
- return -EINVAL;
- }
-
- if (header->length != size - sizeof(*header)) {
- v4l2_err(&dev->v4l2_dev,
- "invalid message length: %u bytes (expected %zu bytes)\n",
- header->length, size - sizeof(*header));
+ if (size > mbox->size)
return -EINVAL;
- }
-
- v4l2_dbg(2, debug, &dev->v4l2_dev,
- "write command message: type %s, body length %d\n",
- msg_type_name(header->type), header->length);
mutex_lock(&mbox->lock);
- regmap_read(dev->sram, mbox->tail, &tail);
+ regmap_read(sram, mbox->tail, &tail);
if (tail > mbox->size) {
- v4l2_err(&dev->v4l2_dev,
- "invalid tail (0x%x): must be smaller than mailbox size (0x%zx)\n",
- tail, mbox->size);
err = -EIO;
goto out;
}
size_no_wrap = min(size, mbox->size - (size_t)tail);
- regmap_bulk_write(dev->sram, mbox->data + tail, src, size_no_wrap / 4);
- regmap_bulk_write(dev->sram, mbox->data,
- src + size_no_wrap, (size - size_no_wrap) / 4);
- regmap_write(dev->sram, mbox->tail, (tail + size) % mbox->size);
+ regmap_bulk_write(sram, mbox->data + tail,
+ src, size_no_wrap / stride);
+ regmap_bulk_write(sram, mbox->data,
+ src + (size_no_wrap / sizeof(*src)),
+ (size - size_no_wrap) / stride);
+ regmap_write(sram, mbox->tail, (tail + size) % mbox->size);
out:
mutex_unlock(&mbox->lock);
return err;
}
-static ssize_t allegro_mbox_read(struct allegro_dev *dev,
- struct allegro_mbox *mbox,
- void *dst, size_t nbyte)
+static ssize_t allegro_mbox_read(struct allegro_mbox *mbox,
+ u32 *dst, size_t nbyte)
{
- struct mcu_msg_header *header;
+ struct {
+ u16 length;
+ u16 type;
+ } __attribute__ ((__packed__)) *header;
+ struct regmap *sram = mbox->dev->sram;
unsigned int head;
ssize_t size;
size_t body_no_wrap;
+ int stride = regmap_get_reg_stride(sram);
- regmap_read(dev->sram, mbox->head, &head);
- if (head > mbox->size) {
- v4l2_err(&dev->v4l2_dev,
- "invalid head (0x%x): must be smaller than mailbox size (0x%zx)\n",
- head, mbox->size);
+ regmap_read(sram, mbox->head, &head);
+ if (head > mbox->size)
return -EIO;
- }
/* Assume that the header does not wrap. */
- regmap_bulk_read(dev->sram, mbox->data + head,
- dst, sizeof(*header) / 4);
- header = dst;
+ regmap_bulk_read(sram, mbox->data + head,
+ dst, sizeof(*header) / stride);
+ header = (void *)dst;
size = header->length + sizeof(*header);
- if (size > mbox->size || size & 0x3) {
- v4l2_err(&dev->v4l2_dev,
- "invalid message length: %zu bytes (maximum %zu bytes)\n",
- header->length + sizeof(*header), mbox->size);
+ if (size > mbox->size || size & 0x3)
return -EIO;
- }
- if (size > nbyte) {
- v4l2_err(&dev->v4l2_dev,
- "destination buffer too small: %zu bytes (need %zu bytes)\n",
- nbyte, size);
+ if (size > nbyte)
return -EINVAL;
- }
/*
* The message might wrap within the mailbox. If the message does not
*/
body_no_wrap = min((size_t)header->length,
(size_t)(mbox->size - (head + sizeof(*header))));
- regmap_bulk_read(dev->sram, mbox->data + head + sizeof(*header),
- dst + sizeof(*header), body_no_wrap / 4);
- regmap_bulk_read(dev->sram, mbox->data,
- dst + sizeof(*header) + body_no_wrap,
- (header->length - body_no_wrap) / 4);
+ regmap_bulk_read(sram, mbox->data + head + sizeof(*header),
+ dst + (sizeof(*header) / sizeof(*dst)),
+ body_no_wrap / stride);
+ regmap_bulk_read(sram, mbox->data,
+ dst + (sizeof(*header) + body_no_wrap) / sizeof(*dst),
+ (header->length - body_no_wrap) / stride);
- regmap_write(dev->sram, mbox->head, (head + size) % mbox->size);
-
- v4l2_dbg(2, debug, &dev->v4l2_dev,
- "read status message: type %s, body length %d\n",
- msg_type_name(header->type), header->length);
+ regmap_write(sram, mbox->head, (head + size) % mbox->size);
return size;
}
ssize_t size = sizeof(*header) + header->length;
int err;
- err = allegro_mbox_write(dev, mbox, msg, size);
+ err = allegro_mbox_write(mbox, msg, size);
if (err)
goto out;
if (!msg)
return;
- size = allegro_mbox_read(dev, mbox, msg, sizeof(*msg));
+ size = allegro_mbox_read(mbox, (u32 *)msg, sizeof(*msg));
if (size < 0)
goto out;
struct allegro_channel *channel;
int err = 0;
- if (msg->header.length != sizeof(*msg) - sizeof(msg->header))
- v4l2_warn(&dev->v4l2_dev,
- "received message has %d bytes, but expected %zu\n",
- msg->header.length,
- sizeof(*msg) - sizeof(msg->header));
-
channel = allegro_find_channel_by_user_id(dev, msg->user_id);
if (IS_ERR(channel)) {
v4l2_warn(&dev->v4l2_dev,
{
struct allegro_channel *channel;
- if (msg->header.length != sizeof(*msg) - sizeof(msg->header))
- v4l2_warn(&dev->v4l2_dev,
- "received message has %d bytes, but expected %zu\n",
- msg->header.length,
- sizeof(*msg) - sizeof(msg->header));
-
channel = allegro_find_channel_by_channel_id(dev, msg->channel_id);
if (IS_ERR(channel)) {
v4l2_err(&dev->v4l2_dev,