Loading drivers/soundwire/soundwire.c +42 −0 Original line number Diff line number Diff line Loading @@ -476,6 +476,15 @@ int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg, return -EINVAL; master = dev->master; if (dev->group_id) { if (master->gr_sid != dev_num) { if (!master->gr_sid) master->gr_sid = dev_num; else return 0; } dev_num = dev->group_id; } if (master->bulk_write) return master->bulk_write(master, dev_num, reg, buf, len); Loading @@ -499,6 +508,16 @@ int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr, struct swr_master *master = dev->master; if (!master) return -EINVAL; if (dev->group_id) { if (master->gr_sid != dev_num) { if (!master->gr_sid) master->gr_sid = dev_num; else return 0; } dev_num = dev->group_id; } return master->write(master, dev_num, reg_addr, buf); } EXPORT_SYMBOL(swr_write); Loading Loading @@ -588,6 +607,29 @@ int swr_reset_device(struct swr_device *swr_dev) } EXPORT_SYMBOL(swr_reset_device); /** * swr_set_device_group - Assign group id to the slave devices * @swr_dev: pointer to soundwire slave device * @id: group id to be assigned to slave device * Context: can sleep * * This API will be called either from soundwire master or slave * device to assign group id. */ int swr_set_device_group(struct swr_device *swr_dev, u8 id) { struct swr_master *master = swr_dev->master; if (!swr_dev) return -EINVAL; swr_dev->group_id = id; if (!id && master) master->gr_sid = 0; return 0; } EXPORT_SYMBOL(swr_set_device_group); static int swr_drv_probe(struct device *dev) { const struct swr_driver *sdrv = to_swr_driver(dev->driver); Loading drivers/soundwire/swr-wcd-ctrl.c +31 −1 Original line number Diff line number Diff line Loading @@ -761,7 +761,13 @@ static int swrm_connect_port(struct swr_master *master, swrm_get_port_config(master); swr_port_response(master, portinfo->tid); if (swrm->num_rx_chs > 1) { swrm->num_cfg_devs += 1; if (swrm->num_rx_chs == swrm->num_cfg_devs) swrm_apply_port_config(master); } else { swrm_apply_port_config(master); } mutex_unlock(&swrm->mlock); return 0; Loading Loading @@ -838,6 +844,8 @@ static int swrm_disconnect_port(struct swr_master *master, master->num_port -= portinfo->num_port; swr_port_response(master, portinfo->tid); if (swrm->num_rx_chs > 1) swrm->num_cfg_devs -= 1; mutex_unlock(&swrm->mlock); dev_dbg(&master->dev, "%s: master active ports: %d\n", Loading Loading @@ -1157,6 +1165,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->rcmd_id = 0; swrm->wcmd_id = 0; swrm->slave_status = 0; swrm->num_rx_chs = 0; swrm->state = SWR_MSTR_RESUME; init_completion(&swrm->reset); init_completion(&swrm->broadcast); Loading Loading @@ -1442,6 +1451,27 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) } mutex_unlock(&swrm->mlock); break; case SWR_SET_NUM_RX_CH: if (!data) { dev_err(swrm->dev, "%s: data is NULL\n", __func__); ret = -EINVAL; } else { mutex_lock(&swrm->mlock); swrm->num_rx_chs = *(int *)data; if (swrm->num_rx_chs > 1) { list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_set_device_group(swr_dev, SWR_BROADCAST); if (ret) dev_err(swrm->dev, "%s: set num ch failed\n", __func__); } } mutex_unlock(&swrm->mlock); } break; default: dev_err(swrm->dev, "%s: swr master unknown id %d\n", __func__, id); Loading drivers/soundwire/swr-wcd-ctrl.h +2 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,8 @@ struct swr_mstr_ctrl { struct list_head mport_list; int state; struct platform_device *pdev; int num_rx_chs; u8 num_cfg_devs; }; #endif /* _SWR_WCD_CTRL_H */ include/linux/soundwire/soundwire.h +14 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,14 @@ extern struct bus_type soundwire_type; */ #define SWR_MAX_MSTR_PORT_NUM (SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM) /* Indicates soundwire devices group information */ enum { SWR_GROUP_NONE = 0, SWR_GROUP_12 = 12, SWR_GROUP_13 = 13, SWR_BROADCAST = 15, }; /* * struct swr_port_info - represent soundwire frame shape * @dev_id: logical device number of the soundwire slave device Loading Loading @@ -112,6 +120,7 @@ struct swr_reg { * @last_tid: size of table port_txn (can't grow beyond 256 since * tid is 8 bits) * @num_port: number of active ports on soundwire master * @gr_sid: slave id used by the group for write operations * @connect_port: callback for configuration of soundwire port(s) * @disconnect_port: callback for disable of soundwire port(s) * @read: callback for soundwire slave register read Loading @@ -131,6 +140,7 @@ struct swr_master { u8 last_tid; u8 num_port; u8 num_dev; u8 gr_sid; int (*connect_port)(struct swr_master *mstr, struct swr_params *txn); int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn); int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr, Loading Loading @@ -159,6 +169,7 @@ static inline struct swr_master *to_swr_master(struct device *dev) * @dev: driver model representation of the device * @addr: represents "ea-addr" which is unique-id of soundwire slave * device * @group_id: group id supported by the slave device */ struct swr_device { char name[SOUNDWIRE_NAME_SIZE]; Loading @@ -168,6 +179,7 @@ struct swr_device { u8 dev_num; struct device dev; unsigned long addr; u8 group_id; }; static inline struct swr_device *to_swr_device(struct device *dev) Loading Loading @@ -270,6 +282,8 @@ extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, extern int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port); extern int swr_set_device_group(struct swr_device *swr_dev, u8 id); extern int swr_driver_register(struct swr_driver *drv); extern void swr_driver_unregister(struct swr_driver *drv); Loading include/linux/soundwire/swr-wcd.h +2 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ enum { SWR_CH_MAP, SWR_DEVICE_DOWN, SWR_DEVICE_UP, SWR_SUBSYS_RESTART SWR_SUBSYS_RESTART, SWR_SET_NUM_RX_CH, }; struct swr_mstr_port { Loading Loading
drivers/soundwire/soundwire.c +42 −0 Original line number Diff line number Diff line Loading @@ -476,6 +476,15 @@ int swr_bulk_write(struct swr_device *dev, u8 dev_num, void *reg, return -EINVAL; master = dev->master; if (dev->group_id) { if (master->gr_sid != dev_num) { if (!master->gr_sid) master->gr_sid = dev_num; else return 0; } dev_num = dev->group_id; } if (master->bulk_write) return master->bulk_write(master, dev_num, reg, buf, len); Loading @@ -499,6 +508,16 @@ int swr_write(struct swr_device *dev, u8 dev_num, u16 reg_addr, struct swr_master *master = dev->master; if (!master) return -EINVAL; if (dev->group_id) { if (master->gr_sid != dev_num) { if (!master->gr_sid) master->gr_sid = dev_num; else return 0; } dev_num = dev->group_id; } return master->write(master, dev_num, reg_addr, buf); } EXPORT_SYMBOL(swr_write); Loading Loading @@ -588,6 +607,29 @@ int swr_reset_device(struct swr_device *swr_dev) } EXPORT_SYMBOL(swr_reset_device); /** * swr_set_device_group - Assign group id to the slave devices * @swr_dev: pointer to soundwire slave device * @id: group id to be assigned to slave device * Context: can sleep * * This API will be called either from soundwire master or slave * device to assign group id. */ int swr_set_device_group(struct swr_device *swr_dev, u8 id) { struct swr_master *master = swr_dev->master; if (!swr_dev) return -EINVAL; swr_dev->group_id = id; if (!id && master) master->gr_sid = 0; return 0; } EXPORT_SYMBOL(swr_set_device_group); static int swr_drv_probe(struct device *dev) { const struct swr_driver *sdrv = to_swr_driver(dev->driver); Loading
drivers/soundwire/swr-wcd-ctrl.c +31 −1 Original line number Diff line number Diff line Loading @@ -761,7 +761,13 @@ static int swrm_connect_port(struct swr_master *master, swrm_get_port_config(master); swr_port_response(master, portinfo->tid); if (swrm->num_rx_chs > 1) { swrm->num_cfg_devs += 1; if (swrm->num_rx_chs == swrm->num_cfg_devs) swrm_apply_port_config(master); } else { swrm_apply_port_config(master); } mutex_unlock(&swrm->mlock); return 0; Loading Loading @@ -838,6 +844,8 @@ static int swrm_disconnect_port(struct swr_master *master, master->num_port -= portinfo->num_port; swr_port_response(master, portinfo->tid); if (swrm->num_rx_chs > 1) swrm->num_cfg_devs -= 1; mutex_unlock(&swrm->mlock); dev_dbg(&master->dev, "%s: master active ports: %d\n", Loading Loading @@ -1157,6 +1165,7 @@ static int swrm_probe(struct platform_device *pdev) swrm->rcmd_id = 0; swrm->wcmd_id = 0; swrm->slave_status = 0; swrm->num_rx_chs = 0; swrm->state = SWR_MSTR_RESUME; init_completion(&swrm->reset); init_completion(&swrm->broadcast); Loading Loading @@ -1442,6 +1451,27 @@ int swrm_wcd_notify(struct platform_device *pdev, u32 id, void *data) } mutex_unlock(&swrm->mlock); break; case SWR_SET_NUM_RX_CH: if (!data) { dev_err(swrm->dev, "%s: data is NULL\n", __func__); ret = -EINVAL; } else { mutex_lock(&swrm->mlock); swrm->num_rx_chs = *(int *)data; if (swrm->num_rx_chs > 1) { list_for_each_entry(swr_dev, &mstr->devices, dev_list) { ret = swr_set_device_group(swr_dev, SWR_BROADCAST); if (ret) dev_err(swrm->dev, "%s: set num ch failed\n", __func__); } } mutex_unlock(&swrm->mlock); } break; default: dev_err(swrm->dev, "%s: swr master unknown id %d\n", __func__, id); Loading
drivers/soundwire/swr-wcd-ctrl.h +2 −0 Original line number Diff line number Diff line Loading @@ -94,6 +94,8 @@ struct swr_mstr_ctrl { struct list_head mport_list; int state; struct platform_device *pdev; int num_rx_chs; u8 num_cfg_devs; }; #endif /* _SWR_WCD_CTRL_H */
include/linux/soundwire/soundwire.h +14 −0 Original line number Diff line number Diff line Loading @@ -29,6 +29,14 @@ extern struct bus_type soundwire_type; */ #define SWR_MAX_MSTR_PORT_NUM (SWR_MAX_DEV_NUM * SWR_MAX_DEV_PORT_NUM) /* Indicates soundwire devices group information */ enum { SWR_GROUP_NONE = 0, SWR_GROUP_12 = 12, SWR_GROUP_13 = 13, SWR_BROADCAST = 15, }; /* * struct swr_port_info - represent soundwire frame shape * @dev_id: logical device number of the soundwire slave device Loading Loading @@ -112,6 +120,7 @@ struct swr_reg { * @last_tid: size of table port_txn (can't grow beyond 256 since * tid is 8 bits) * @num_port: number of active ports on soundwire master * @gr_sid: slave id used by the group for write operations * @connect_port: callback for configuration of soundwire port(s) * @disconnect_port: callback for disable of soundwire port(s) * @read: callback for soundwire slave register read Loading @@ -131,6 +140,7 @@ struct swr_master { u8 last_tid; u8 num_port; u8 num_dev; u8 gr_sid; int (*connect_port)(struct swr_master *mstr, struct swr_params *txn); int (*disconnect_port)(struct swr_master *mstr, struct swr_params *txn); int (*read)(struct swr_master *mstr, u8 dev_num, u16 reg_addr, Loading Loading @@ -159,6 +169,7 @@ static inline struct swr_master *to_swr_master(struct device *dev) * @dev: driver model representation of the device * @addr: represents "ea-addr" which is unique-id of soundwire slave * device * @group_id: group id supported by the slave device */ struct swr_device { char name[SOUNDWIRE_NAME_SIZE]; Loading @@ -168,6 +179,7 @@ struct swr_device { u8 dev_num; struct device dev; unsigned long addr; u8 group_id; }; static inline struct swr_device *to_swr_device(struct device *dev) Loading Loading @@ -270,6 +282,8 @@ extern int swr_connect_port(struct swr_device *dev, u8 *port_id, u8 num_port, extern int swr_disconnect_port(struct swr_device *dev, u8 *port_id, u8 num_port); extern int swr_set_device_group(struct swr_device *swr_dev, u8 id); extern int swr_driver_register(struct swr_driver *drv); extern void swr_driver_unregister(struct swr_driver *drv); Loading
include/linux/soundwire/swr-wcd.h +2 −1 Original line number Diff line number Diff line Loading @@ -21,7 +21,8 @@ enum { SWR_CH_MAP, SWR_DEVICE_DOWN, SWR_DEVICE_UP, SWR_SUBSYS_RESTART SWR_SUBSYS_RESTART, SWR_SET_NUM_RX_CH, }; struct swr_mstr_port { Loading