1 // SPDX-License-Identifier: GPL-2.0 2 // Copyright(c) 2015-17 Intel Corporation. 3 4 #include <linux/module.h> 5 #include <linux/mod_devicetable.h> 6 #include <linux/pm_domain.h> 7 #include <linux/soundwire/sdw.h> 8 #include <linux/soundwire/sdw_type.h> 9 10 /** 11 * sdw_get_device_id - find the matching SoundWire device id 12 * @slave: SoundWire Slave Device 13 * @drv: SoundWire Slave Driver 14 * 15 * The match is done by comparing the mfg_id and part_id from the 16 * struct sdw_device_id. 17 */ 18 static const struct sdw_device_id * 19 sdw_get_device_id(struct sdw_slave *slave, struct sdw_driver *drv) 20 { 21 const struct sdw_device_id *id = drv->id_table; 22 23 while (id && id->mfg_id) { 24 if (slave->id.mfg_id == id->mfg_id && 25 slave->id.part_id == id->part_id) 26 return id; 27 id++; 28 } 29 30 return NULL; 31 } 32 33 static int sdw_bus_match(struct device *dev, struct device_driver *ddrv) 34 { 35 struct sdw_slave *slave = dev_to_sdw_dev(dev); 36 struct sdw_driver *drv = drv_to_sdw_driver(ddrv); 37 38 return !!sdw_get_device_id(slave, drv); 39 } 40 41 int sdw_slave_modalias(const struct sdw_slave *slave, char *buf, size_t size) 42 { 43 /* modalias is sdw:m<mfg_id>p<part_id> */ 44 45 return snprintf(buf, size, "sdw:m%04Xp%04X\n", 46 slave->id.mfg_id, slave->id.part_id); 47 } 48 49 static int sdw_uevent(struct device *dev, struct kobj_uevent_env *env) 50 { 51 struct sdw_slave *slave = dev_to_sdw_dev(dev); 52 char modalias[32]; 53 54 sdw_slave_modalias(slave, modalias, sizeof(modalias)); 55 56 if (add_uevent_var(env, "MODALIAS=%s", modalias)) 57 return -ENOMEM; 58 59 return 0; 60 } 61 62 struct bus_type sdw_bus_type = { 63 .name = "soundwire", 64 .match = sdw_bus_match, 65 .uevent = sdw_uevent, 66 }; 67 EXPORT_SYMBOL_GPL(sdw_bus_type); 68 69 static int sdw_drv_probe(struct device *dev) 70 { 71 struct sdw_slave *slave = dev_to_sdw_dev(dev); 72 struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); 73 const struct sdw_device_id *id; 74 int ret; 75 76 id = sdw_get_device_id(slave, drv); 77 if (!id) 78 return -ENODEV; 79 80 slave->ops = drv->ops; 81 82 /* 83 * attach to power domain but don't turn on (last arg) 84 */ 85 ret = dev_pm_domain_attach(dev, false); 86 if (ret) 87 return ret; 88 89 ret = drv->probe(slave, id); 90 if (ret) { 91 dev_err(dev, "Probe of %s failed: %d\n", drv->name, ret); 92 dev_pm_domain_detach(dev, false); 93 return ret; 94 } 95 96 /* device is probed so let's read the properties now */ 97 if (slave->ops && slave->ops->read_prop) 98 slave->ops->read_prop(slave); 99 100 /* 101 * Check for valid clk_stop_timeout, use DisCo worst case value of 102 * 300ms 103 * 104 * TODO: check the timeouts and driver removal case 105 */ 106 if (slave->prop.clk_stop_timeout == 0) 107 slave->prop.clk_stop_timeout = 300; 108 109 slave->bus->clk_stop_timeout = max_t(u32, slave->bus->clk_stop_timeout, 110 slave->prop.clk_stop_timeout); 111 112 return 0; 113 } 114 115 static int sdw_drv_remove(struct device *dev) 116 { 117 struct sdw_slave *slave = dev_to_sdw_dev(dev); 118 struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); 119 int ret = 0; 120 121 if (drv->remove) 122 ret = drv->remove(slave); 123 124 dev_pm_domain_detach(dev, false); 125 126 return ret; 127 } 128 129 static void sdw_drv_shutdown(struct device *dev) 130 { 131 struct sdw_slave *slave = dev_to_sdw_dev(dev); 132 struct sdw_driver *drv = drv_to_sdw_driver(dev->driver); 133 134 if (drv->shutdown) 135 drv->shutdown(slave); 136 } 137 138 /** 139 * __sdw_register_driver() - register a SoundWire Slave driver 140 * @drv: driver to register 141 * @owner: owning module/driver 142 * 143 * Return: zero on success, else a negative error code. 144 */ 145 int __sdw_register_driver(struct sdw_driver *drv, struct module *owner) 146 { 147 drv->driver.bus = &sdw_bus_type; 148 149 if (!drv->probe) { 150 pr_err("driver %s didn't provide SDW probe routine\n", 151 drv->name); 152 return -EINVAL; 153 } 154 155 drv->driver.owner = owner; 156 drv->driver.probe = sdw_drv_probe; 157 158 if (drv->remove) 159 drv->driver.remove = sdw_drv_remove; 160 161 if (drv->shutdown) 162 drv->driver.shutdown = sdw_drv_shutdown; 163 164 return driver_register(&drv->driver); 165 } 166 EXPORT_SYMBOL_GPL(__sdw_register_driver); 167 168 /** 169 * sdw_unregister_driver() - unregisters the SoundWire Slave driver 170 * @drv: driver to unregister 171 */ 172 void sdw_unregister_driver(struct sdw_driver *drv) 173 { 174 driver_unregister(&drv->driver); 175 } 176 EXPORT_SYMBOL_GPL(sdw_unregister_driver); 177 178 static int __init sdw_bus_init(void) 179 { 180 return bus_register(&sdw_bus_type); 181 } 182 183 static void __exit sdw_bus_exit(void) 184 { 185 bus_unregister(&sdw_bus_type); 186 } 187 188 postcore_initcall(sdw_bus_init); 189 module_exit(sdw_bus_exit); 190 191 MODULE_DESCRIPTION("SoundWire bus"); 192 MODULE_LICENSE("GPL v2"); 193