Loading drivers/mfd/wcd9xxx-core.c +63 −0 Original line number Original line Diff line number Diff line Loading @@ -672,6 +672,69 @@ static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx, return ret; return ret; } } /* * wcd9xxx_slim_bulk_write: API to write multiple registers with one descriptor * @wcd9xxx: Handle to the wcd9xxx core * @wcd9xxx_reg_val: structure holding register and values to be written * @size: Indicates number of messages to be written with one descriptor * @is_interface: Indicates whether the register is for slim interface or for * general registers. * @return: returns 0 if success or error information to the caller in case * of failure. */ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, struct wcd9xxx_reg_val *bulk_reg, unsigned int size, bool is_interface) { int ret, i; struct slim_val_inf *msgs; unsigned short reg; if (!bulk_reg || !size || !wcd9xxx) { pr_err("%s: Invalid parameters\n", __func__); return -EINVAL; } msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL); if (!msgs) { ret = -ENOMEM; goto mem_fail; } mutex_lock(&wcd9xxx->io_lock); reg = bulk_reg->reg; for (i = 0; i < size; i++) { msgs[i].start_offset = WCD9XXX_REGISTER_START_OFFSET + (bulk_reg->reg & 0xFF); msgs[i].num_bytes = bulk_reg->bytes; msgs[i].wbuf = bulk_reg->buf; bulk_reg++; } ret = wcd9xxx_page_write(wcd9xxx, ®); if (ret) { pr_err("%s: Page write error for reg: 0x%x\n", __func__, reg); goto err; } ret = slim_bulk_msg_write(is_interface ? wcd9xxx->slim_slave : wcd9xxx->slim, SLIM_MSG_MT_CORE, SLIM_MSG_MC_CHANGE_VALUE, msgs, size, NULL, NULL); if (ret) pr_err("%s: Error, Codec bulk write failed (%d)\n", __func__, ret); /* 700 usec sleep is needed as per HW requirement */ usleep_range(700, 710); err: mutex_unlock(&wcd9xxx->io_lock); kfree(msgs); mem_fail: return ret; } EXPORT_SYMBOL(wcd9xxx_slim_bulk_write); static struct mfd_cell tabla1x_devs[] = { static struct mfd_cell tabla1x_devs[] = { { { .name = "tabla1x_codec", .name = "tabla1x_codec", Loading include/linux/mfd/wcd9xxx/core.h +10 −0 Original line number Original line Diff line number Diff line Loading @@ -272,6 +272,12 @@ struct wcd9xxx { u8 prev_pg; u8 prev_pg; }; }; struct wcd9xxx_reg_val { unsigned short reg; /* register address */ u8 *buf; /* buffer to be written to reg. addr */ int bytes; /* number of bytes to be written */ }; int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, u8 val); u8 val); Loading @@ -281,6 +287,10 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, u32 bw_ops, bool commit); u32 bw_ops, bool commit); int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, struct wcd9xxx_reg_val *bulk_reg, unsigned int size, bool interface); #if defined(CONFIG_WCD9310_CODEC) || \ #if defined(CONFIG_WCD9310_CODEC) || \ defined(CONFIG_WCD9304_CODEC) || \ defined(CONFIG_WCD9304_CODEC) || \ defined(CONFIG_WCD9320_CODEC) || \ defined(CONFIG_WCD9320_CODEC) || \ Loading Loading
drivers/mfd/wcd9xxx-core.c +63 −0 Original line number Original line Diff line number Diff line Loading @@ -672,6 +672,69 @@ static int wcd9xxx_slim_write_device(struct wcd9xxx *wcd9xxx, return ret; return ret; } } /* * wcd9xxx_slim_bulk_write: API to write multiple registers with one descriptor * @wcd9xxx: Handle to the wcd9xxx core * @wcd9xxx_reg_val: structure holding register and values to be written * @size: Indicates number of messages to be written with one descriptor * @is_interface: Indicates whether the register is for slim interface or for * general registers. * @return: returns 0 if success or error information to the caller in case * of failure. */ int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, struct wcd9xxx_reg_val *bulk_reg, unsigned int size, bool is_interface) { int ret, i; struct slim_val_inf *msgs; unsigned short reg; if (!bulk_reg || !size || !wcd9xxx) { pr_err("%s: Invalid parameters\n", __func__); return -EINVAL; } msgs = kzalloc(size * (sizeof(struct slim_val_inf)), GFP_KERNEL); if (!msgs) { ret = -ENOMEM; goto mem_fail; } mutex_lock(&wcd9xxx->io_lock); reg = bulk_reg->reg; for (i = 0; i < size; i++) { msgs[i].start_offset = WCD9XXX_REGISTER_START_OFFSET + (bulk_reg->reg & 0xFF); msgs[i].num_bytes = bulk_reg->bytes; msgs[i].wbuf = bulk_reg->buf; bulk_reg++; } ret = wcd9xxx_page_write(wcd9xxx, ®); if (ret) { pr_err("%s: Page write error for reg: 0x%x\n", __func__, reg); goto err; } ret = slim_bulk_msg_write(is_interface ? wcd9xxx->slim_slave : wcd9xxx->slim, SLIM_MSG_MT_CORE, SLIM_MSG_MC_CHANGE_VALUE, msgs, size, NULL, NULL); if (ret) pr_err("%s: Error, Codec bulk write failed (%d)\n", __func__, ret); /* 700 usec sleep is needed as per HW requirement */ usleep_range(700, 710); err: mutex_unlock(&wcd9xxx->io_lock); kfree(msgs); mem_fail: return ret; } EXPORT_SYMBOL(wcd9xxx_slim_bulk_write); static struct mfd_cell tabla1x_devs[] = { static struct mfd_cell tabla1x_devs[] = { { { .name = "tabla1x_codec", .name = "tabla1x_codec", Loading
include/linux/mfd/wcd9xxx/core.h +10 −0 Original line number Original line Diff line number Diff line Loading @@ -272,6 +272,12 @@ struct wcd9xxx { u8 prev_pg; u8 prev_pg; }; }; struct wcd9xxx_reg_val { unsigned short reg; /* register address */ u8 *buf; /* buffer to be written to reg. addr */ int bytes; /* number of bytes to be written */ }; int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); int wcd9xxx_interface_reg_read(struct wcd9xxx *wcd9xxx, unsigned short reg); int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, int wcd9xxx_interface_reg_write(struct wcd9xxx *wcd9xxx, unsigned short reg, u8 val); u8 val); Loading @@ -281,6 +287,10 @@ int wcd9xxx_slim_write_repeat(struct wcd9xxx *wcd9xxx, unsigned short reg, int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, int wcd9xxx_slim_reserve_bw(struct wcd9xxx *wcd9xxx, u32 bw_ops, bool commit); u32 bw_ops, bool commit); int wcd9xxx_slim_bulk_write(struct wcd9xxx *wcd9xxx, struct wcd9xxx_reg_val *bulk_reg, unsigned int size, bool interface); #if defined(CONFIG_WCD9310_CODEC) || \ #if defined(CONFIG_WCD9310_CODEC) || \ defined(CONFIG_WCD9304_CODEC) || \ defined(CONFIG_WCD9304_CODEC) || \ defined(CONFIG_WCD9320_CODEC) || \ defined(CONFIG_WCD9320_CODEC) || \ Loading