Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /* NEW DEFINES FOR REGS */
- #define ALVIUM_REG_SIZE_SHIFT 8
- #define ALVIUM_REG_ADDR_MASK 0xff
- #define ALVIUM_REG_8BIT(n) ((1U << ALVIUM_REG_SIZE_SHIFT) | (n))
- #define ALVIUM_REG_16BIT(n) ((2U << ALVIUM_REG_SIZE_SHIFT) | (n))
- #define ALVIUM_REG_32BIT(n) ((4U << ALVIUM_REG_SIZE_SHIFT) | (n))
- #define ALVIUM_REG_64BIT(n) ((8U << ALVIUM_REG_SIZE_SHIFT) | (n))
- #define ALVIUM_BCRM_EXPOSURE_AUTO_8RW ALVIUM_REG_8BIT(0x01a0)
- #define ALVIUM_BCRM_REG_ADDR ALVIUM_REG_16BIT(0x0014)
- #define ALVIUM_BCRM_REG_VERSION ALVIUM_REG_32BIT(0x0000)
- #define ALVIUM_BCRM_DEVICE_FIRMWARE_VERSION ALVIUM_REG_64BIT(0x0010)
- #define ALVIUM_BCRM_WRITE_HANDSHAKE_8RW ALVIUM_REG_8BIT(0x0018)
- /* NEW READ FUNCTION */
- static int __always_unused alvium_read(struct alvium_dev *alvium,
- u16 addr, void *val)
- {
- struct i2c_client *client = alvium->i2c_client;
- struct i2c_msg msgs[2] = {0};
- u8 addr_buf[2] = {0};
- u8 *data_buf = NULL;
- u16 reg = 0;
- u32 len = 0;
- int ret;
- reg = (addr & ALVIUM_REG_ADDR_MASK);
- len = (addr >> ALVIUM_REG_SIZE_SHIFT);
- if (WARN_ON(len > 8))
- return -EINVAL;
- data_buf = kmalloc_array(len,
- sizeof(u8),
- GFP_KERNEL);
- put_unaligned_be16(reg, addr_buf);
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = ARRAY_SIZE(addr_buf);
- msgs[0].buf = addr_buf;
- msgs[1].addr = client->addr;
- msgs[1].flags = I2C_M_RD;
- msgs[1].len = len;
- msgs[1].buf = data_buf;
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret != ARRAY_SIZE(msgs))
- return -EIO;
- switch (len) {
- case 1:
- *(u8 *)val = data_buf[0];
- break;
- case 2:
- *(u16 *)val = get_unaligned_be16(data_buf);
- break;
- case 4:
- *(u32 *)val = get_unaligned_be32(data_buf);
- break;
- case 8:
- *(u64 *)val = get_unaligned_be64(data_buf);
- break;
- default:
- return -EINVAL;
- }
- return 0;
- }
- /* NEW WRITE FUNCTION */
- static int __always_unused alvium_write(struct alvium_dev *alvium,
- u16 addr, void *val)
- {
- struct i2c_client *client = alvium->i2c_client;
- struct i2c_msg msgs[2] = {0};
- u8 addr_buf[2] = {0};
- u8 *data_buf = NULL;
- u16 reg = 0;
- u32 len = 0;
- int ret;
- reg = (addr & ALVIUM_REG_ADDR_MASK);
- len = (addr >> ALVIUM_REG_SIZE_SHIFT);
- if (WARN_ON(len > 8))
- return -EINVAL;
- data_buf = kmalloc_array(len,
- sizeof(u8),
- GFP_KERNEL);
- put_unaligned_be16(reg, addr_buf);
- switch (len) {
- case 1:
- data_buf = val;
- break;
- case 2:
- put_unaligned_be16(*(u64 *)val, data_buf);
- break;
- case 4:
- put_unaligned_be32(*(u32 *)val, data_buf);
- break;
- case 8:
- put_unaligned_be64(*(u16 *)val, data_buf);
- break;
- default:
- return -EINVAL;
- }
- msgs[0].addr = client->addr;
- msgs[0].flags = 0;
- msgs[0].len = ARRAY_SIZE(addr_buf);
- msgs[0].buf = addr_buf;
- msgs[1].addr = client->addr;
- msgs[1].flags = 0;
- msgs[1].len = len;
- msgs[1].buf = data_buf;
- ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs));
- if (ret != ARRAY_SIZE(msgs))
- return -EIO;
- return 0;
- }
- # USAGE
- ret = alvium_read(alvium, ALVIUM_BCRM_REG_VERSION, &tmp);
- ret = alvium_write(alvium, ALVIUM_BCRM_WRITE_HANDSHAKE_8RW, &test);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement