cs40l50-vibra.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * CS40L50 Advanced Haptic Driver with waveform memory,
  4. * integrated DSP, and closed-loop algorithms
  5. *
  6. * Copyright 2024 Cirrus Logic, Inc.
  7. *
  8. * Author: James Ogletree <james.ogletree@cirrus.com>
  9. */
  10. #include <linux/bitfield.h>
  11. #include <linux/input.h>
  12. #include <linux/mfd/cs40l50.h>
  13. #include <linux/platform_device.h>
  14. #include <linux/pm_runtime.h>
  15. /* Wavetables */
  16. #define CS40L50_RAM_INDEX_START 0x1000000
  17. #define CS40L50_RAM_INDEX_END 0x100007F
  18. #define CS40L50_RTH_INDEX_START 0x1400000
  19. #define CS40L50_RTH_INDEX_END 0x1400001
  20. #define CS40L50_ROM_INDEX_START 0x1800000
  21. #define CS40L50_ROM_INDEX_END 0x180001A
  22. #define CS40L50_TYPE_PCM 8
  23. #define CS40L50_TYPE_PWLE 12
  24. #define CS40L50_PCM_ID 0x0
  25. #define CS40L50_OWT_CUSTOM_DATA_SIZE 2
  26. #define CS40L50_CUSTOM_DATA_MASK 0xFFFFU
  27. /* DSP */
  28. #define CS40L50_GPIO_BASE 0x2804140
  29. #define CS40L50_OWT_BASE 0x2805C34
  30. #define CS40L50_OWT_SIZE 0x2805C38
  31. #define CS40L50_OWT_NEXT 0x2805C3C
  32. #define CS40L50_EFFECTS_MAX 1
  33. /* GPIO */
  34. #define CS40L50_GPIO_NUM_MASK GENMASK(14, 12)
  35. #define CS40L50_GPIO_EDGE_MASK BIT(15)
  36. #define CS40L50_GPIO_MAPPING_NONE 0
  37. #define CS40L50_GPIO_DISABLE 0x1FF
  38. enum cs40l50_bank_type {
  39. CS40L50_WVFRM_BANK_RAM,
  40. CS40L50_WVFRM_BANK_ROM,
  41. CS40L50_WVFRM_BANK_OWT,
  42. CS40L50_WVFRM_BANK_NUM,
  43. };
  44. /* Describes an area in DSP memory populated by effects */
  45. struct cs40l50_bank {
  46. enum cs40l50_bank_type type;
  47. u32 base_index;
  48. u32 max_index;
  49. };
  50. struct cs40l50_effect {
  51. enum cs40l50_bank_type type;
  52. struct list_head list;
  53. u32 gpio_reg;
  54. u32 index;
  55. int id;
  56. };
  57. /* Describes haptic interface of loaded DSP firmware */
  58. struct cs40l50_vibra_dsp {
  59. struct cs40l50_bank *banks;
  60. u32 gpio_base_reg;
  61. u32 owt_offset_reg;
  62. u32 owt_size_reg;
  63. u32 owt_base_reg;
  64. u32 push_owt_cmd;
  65. u32 delete_owt_cmd;
  66. u32 stop_cmd;
  67. int (*write)(struct device *dev, struct regmap *regmap, u32 val);
  68. };
  69. /* Describes configuration and state of haptic operations */
  70. struct cs40l50_vibra {
  71. struct device *dev;
  72. struct regmap *regmap;
  73. struct input_dev *input;
  74. struct workqueue_struct *vib_wq;
  75. struct list_head effect_head;
  76. struct cs40l50_vibra_dsp dsp;
  77. };
  78. struct cs40l50_work {
  79. struct cs40l50_vibra *vib;
  80. struct ff_effect *effect;
  81. struct work_struct work;
  82. s16 *custom_data;
  83. int custom_len;
  84. int count;
  85. int error;
  86. };
  87. static struct cs40l50_bank cs40l50_banks[] = {
  88. {
  89. .type = CS40L50_WVFRM_BANK_RAM,
  90. .base_index = CS40L50_RAM_INDEX_START,
  91. .max_index = CS40L50_RAM_INDEX_END,
  92. },
  93. {
  94. .type = CS40L50_WVFRM_BANK_ROM,
  95. .base_index = CS40L50_ROM_INDEX_START,
  96. .max_index = CS40L50_ROM_INDEX_END,
  97. },
  98. {
  99. .type = CS40L50_WVFRM_BANK_OWT,
  100. .base_index = CS40L50_RTH_INDEX_START,
  101. .max_index = CS40L50_RTH_INDEX_END,
  102. },
  103. };
  104. static struct cs40l50_vibra_dsp cs40l50_dsp = {
  105. .banks = cs40l50_banks,
  106. .gpio_base_reg = CS40L50_GPIO_BASE,
  107. .owt_base_reg = CS40L50_OWT_BASE,
  108. .owt_offset_reg = CS40L50_OWT_NEXT,
  109. .owt_size_reg = CS40L50_OWT_SIZE,
  110. .push_owt_cmd = CS40L50_OWT_PUSH,
  111. .delete_owt_cmd = CS40L50_OWT_DELETE,
  112. .stop_cmd = CS40L50_STOP_PLAYBACK,
  113. .write = cs40l50_dsp_write,
  114. };
  115. static struct cs40l50_effect *cs40l50_find_effect(int id, struct list_head *effect_head)
  116. {
  117. struct cs40l50_effect *effect;
  118. list_for_each_entry(effect, effect_head, list)
  119. if (effect->id == id)
  120. return effect;
  121. return NULL;
  122. }
  123. static int cs40l50_effect_bank_set(struct cs40l50_work *work_data,
  124. struct cs40l50_effect *effect)
  125. {
  126. s16 bank_type = work_data->custom_data[0] & CS40L50_CUSTOM_DATA_MASK;
  127. if (bank_type >= CS40L50_WVFRM_BANK_NUM) {
  128. dev_err(work_data->vib->dev, "Invalid bank (%d)\n", bank_type);
  129. return -EINVAL;
  130. }
  131. if (work_data->custom_len > CS40L50_OWT_CUSTOM_DATA_SIZE)
  132. effect->type = CS40L50_WVFRM_BANK_OWT;
  133. else
  134. effect->type = bank_type;
  135. return 0;
  136. }
  137. static int cs40l50_effect_index_set(struct cs40l50_work *work_data,
  138. struct cs40l50_effect *effect)
  139. {
  140. struct cs40l50_vibra *vib = work_data->vib;
  141. struct cs40l50_effect *owt_effect;
  142. u32 base_index, max_index;
  143. base_index = vib->dsp.banks[effect->type].base_index;
  144. max_index = vib->dsp.banks[effect->type].max_index;
  145. effect->index = base_index;
  146. switch (effect->type) {
  147. case CS40L50_WVFRM_BANK_OWT:
  148. list_for_each_entry(owt_effect, &vib->effect_head, list)
  149. if (owt_effect->type == CS40L50_WVFRM_BANK_OWT)
  150. effect->index++;
  151. break;
  152. case CS40L50_WVFRM_BANK_ROM:
  153. case CS40L50_WVFRM_BANK_RAM:
  154. effect->index += work_data->custom_data[1] & CS40L50_CUSTOM_DATA_MASK;
  155. break;
  156. default:
  157. dev_err(vib->dev, "Bank type %d not supported\n", effect->type);
  158. return -EINVAL;
  159. }
  160. if (effect->index > max_index || effect->index < base_index) {
  161. dev_err(vib->dev, "Index out of bounds: %u\n", effect->index);
  162. return -ENOSPC;
  163. }
  164. return 0;
  165. }
  166. static int cs40l50_effect_gpio_mapping_set(struct cs40l50_work *work_data,
  167. struct cs40l50_effect *effect)
  168. {
  169. u16 gpio_edge, gpio_num, button = work_data->effect->trigger.button;
  170. struct cs40l50_vibra *vib = work_data->vib;
  171. if (button) {
  172. gpio_num = FIELD_GET(CS40L50_GPIO_NUM_MASK, button);
  173. gpio_edge = FIELD_GET(CS40L50_GPIO_EDGE_MASK, button);
  174. effect->gpio_reg = vib->dsp.gpio_base_reg + (gpio_num * 8) - gpio_edge;
  175. return regmap_write(vib->regmap, effect->gpio_reg, button);
  176. }
  177. effect->gpio_reg = CS40L50_GPIO_MAPPING_NONE;
  178. return 0;
  179. }
  180. struct cs40l50_owt_header {
  181. u32 type;
  182. u32 data_words;
  183. u32 offset;
  184. } __packed;
  185. static int cs40l50_upload_owt(struct cs40l50_work *work_data)
  186. {
  187. u8 *new_owt_effect_data __free(kfree) = NULL;
  188. struct cs40l50_vibra *vib = work_data->vib;
  189. size_t len = work_data->custom_len * 2;
  190. struct cs40l50_owt_header header;
  191. u32 offset, size;
  192. int error;
  193. error = regmap_read(vib->regmap, vib->dsp.owt_size_reg, &size);
  194. if (error)
  195. return error;
  196. if ((size * sizeof(u32)) < sizeof(header) + len) {
  197. dev_err(vib->dev, "No space in open wavetable for effect\n");
  198. return -ENOSPC;
  199. }
  200. header.type = work_data->custom_data[0] == CS40L50_PCM_ID ? CS40L50_TYPE_PCM :
  201. CS40L50_TYPE_PWLE;
  202. header.offset = sizeof(header) / sizeof(u32);
  203. header.data_words = len / sizeof(u32);
  204. new_owt_effect_data = kmalloc(sizeof(header) + len, GFP_KERNEL);
  205. if (!new_owt_effect_data)
  206. return -ENOMEM;
  207. memcpy(new_owt_effect_data, &header, sizeof(header));
  208. memcpy(new_owt_effect_data + sizeof(header), work_data->custom_data, len);
  209. error = regmap_read(vib->regmap, vib->dsp.owt_offset_reg, &offset);
  210. if (error)
  211. return error;
  212. error = regmap_bulk_write(vib->regmap, vib->dsp.owt_base_reg +
  213. (offset * sizeof(u32)), new_owt_effect_data,
  214. sizeof(header) + len);
  215. if (error)
  216. return error;
  217. error = vib->dsp.write(vib->dev, vib->regmap, vib->dsp.push_owt_cmd);
  218. if (error)
  219. return error;
  220. return 0;
  221. }
  222. static void cs40l50_add_worker(struct work_struct *work)
  223. {
  224. struct cs40l50_work *work_data = container_of(work, struct cs40l50_work, work);
  225. struct cs40l50_vibra *vib = work_data->vib;
  226. struct cs40l50_effect *effect;
  227. bool is_new = false;
  228. int error;
  229. error = pm_runtime_resume_and_get(vib->dev);
  230. if (error)
  231. goto err_exit;
  232. /* Update effect if already uploaded, otherwise create new effect */
  233. effect = cs40l50_find_effect(work_data->effect->id, &vib->effect_head);
  234. if (!effect) {
  235. effect = kzalloc_obj(*effect);
  236. if (!effect) {
  237. error = -ENOMEM;
  238. goto err_pm;
  239. }
  240. effect->id = work_data->effect->id;
  241. is_new = true;
  242. }
  243. error = cs40l50_effect_bank_set(work_data, effect);
  244. if (error)
  245. goto err_free;
  246. error = cs40l50_effect_index_set(work_data, effect);
  247. if (error)
  248. goto err_free;
  249. error = cs40l50_effect_gpio_mapping_set(work_data, effect);
  250. if (error)
  251. goto err_free;
  252. if (effect->type == CS40L50_WVFRM_BANK_OWT)
  253. error = cs40l50_upload_owt(work_data);
  254. err_free:
  255. if (is_new) {
  256. if (error)
  257. kfree(effect);
  258. else
  259. list_add(&effect->list, &vib->effect_head);
  260. }
  261. err_pm:
  262. pm_runtime_put_autosuspend(vib->dev);
  263. err_exit:
  264. work_data->error = error;
  265. }
  266. static int cs40l50_add(struct input_dev *dev, struct ff_effect *effect,
  267. struct ff_effect *old)
  268. {
  269. struct ff_periodic_effect *periodic = &effect->u.periodic;
  270. struct cs40l50_vibra *vib = input_get_drvdata(dev);
  271. struct cs40l50_work work_data;
  272. if (effect->type != FF_PERIODIC || periodic->waveform != FF_CUSTOM) {
  273. dev_err(vib->dev, "Type (%#X) or waveform (%#X) unsupported\n",
  274. effect->type, periodic->waveform);
  275. return -EINVAL;
  276. }
  277. work_data.custom_data = memdup_array_user(effect->u.periodic.custom_data,
  278. effect->u.periodic.custom_len,
  279. sizeof(s16));
  280. if (IS_ERR(work_data.custom_data))
  281. return PTR_ERR(work_data.custom_data);
  282. work_data.custom_len = effect->u.periodic.custom_len;
  283. work_data.vib = vib;
  284. work_data.effect = effect;
  285. INIT_WORK_ONSTACK(&work_data.work, cs40l50_add_worker);
  286. /* Push to the workqueue to serialize with playbacks */
  287. queue_work(vib->vib_wq, &work_data.work);
  288. flush_work(&work_data.work);
  289. destroy_work_on_stack(&work_data.work);
  290. kfree(work_data.custom_data);
  291. return work_data.error;
  292. }
  293. static void cs40l50_start_worker(struct work_struct *work)
  294. {
  295. struct cs40l50_work *work_data = container_of(work, struct cs40l50_work, work);
  296. struct cs40l50_vibra *vib = work_data->vib;
  297. struct cs40l50_effect *start_effect;
  298. if (pm_runtime_resume_and_get(vib->dev) < 0)
  299. goto err_free;
  300. start_effect = cs40l50_find_effect(work_data->effect->id, &vib->effect_head);
  301. if (start_effect) {
  302. while (--work_data->count >= 0) {
  303. vib->dsp.write(vib->dev, vib->regmap, start_effect->index);
  304. usleep_range(work_data->effect->replay.length,
  305. work_data->effect->replay.length + 100);
  306. }
  307. } else {
  308. dev_err(vib->dev, "Effect to play not found\n");
  309. }
  310. pm_runtime_put_autosuspend(vib->dev);
  311. err_free:
  312. kfree(work_data);
  313. }
  314. static void cs40l50_stop_worker(struct work_struct *work)
  315. {
  316. struct cs40l50_work *work_data = container_of(work, struct cs40l50_work, work);
  317. struct cs40l50_vibra *vib = work_data->vib;
  318. if (pm_runtime_resume_and_get(vib->dev) < 0)
  319. return;
  320. vib->dsp.write(vib->dev, vib->regmap, vib->dsp.stop_cmd);
  321. pm_runtime_put_autosuspend(vib->dev);
  322. kfree(work_data);
  323. }
  324. static int cs40l50_playback(struct input_dev *dev, int effect_id, int val)
  325. {
  326. struct cs40l50_vibra *vib = input_get_drvdata(dev);
  327. struct cs40l50_work *work_data;
  328. work_data = kzalloc_obj(*work_data, GFP_ATOMIC);
  329. if (!work_data)
  330. return -ENOMEM;
  331. work_data->vib = vib;
  332. if (val > 0) {
  333. work_data->effect = &dev->ff->effects[effect_id];
  334. work_data->count = val;
  335. INIT_WORK(&work_data->work, cs40l50_start_worker);
  336. } else {
  337. /* Stop the amplifier as device drives only one effect */
  338. INIT_WORK(&work_data->work, cs40l50_stop_worker);
  339. }
  340. queue_work(vib->vib_wq, &work_data->work);
  341. return 0;
  342. }
  343. static void cs40l50_erase_worker(struct work_struct *work)
  344. {
  345. struct cs40l50_work *work_data = container_of(work, struct cs40l50_work, work);
  346. struct cs40l50_effect *erase_effect, *owt_effect;
  347. struct cs40l50_vibra *vib = work_data->vib;
  348. int error;
  349. error = pm_runtime_resume_and_get(vib->dev);
  350. if (error)
  351. goto err_exit;
  352. erase_effect = cs40l50_find_effect(work_data->effect->id, &vib->effect_head);
  353. if (!erase_effect) {
  354. dev_err(vib->dev, "Effect to erase not found\n");
  355. error = -EINVAL;
  356. goto err_pm;
  357. }
  358. if (erase_effect->gpio_reg != CS40L50_GPIO_MAPPING_NONE) {
  359. error = regmap_write(vib->regmap, erase_effect->gpio_reg,
  360. CS40L50_GPIO_DISABLE);
  361. if (error)
  362. goto err_pm;
  363. }
  364. if (erase_effect->type == CS40L50_WVFRM_BANK_OWT) {
  365. error = vib->dsp.write(vib->dev, vib->regmap,
  366. vib->dsp.delete_owt_cmd |
  367. (erase_effect->index & 0xFF));
  368. if (error)
  369. goto err_pm;
  370. list_for_each_entry(owt_effect, &vib->effect_head, list)
  371. if (owt_effect->type == CS40L50_WVFRM_BANK_OWT &&
  372. owt_effect->index > erase_effect->index)
  373. owt_effect->index--;
  374. }
  375. list_del(&erase_effect->list);
  376. kfree(erase_effect);
  377. err_pm:
  378. pm_runtime_put_autosuspend(vib->dev);
  379. err_exit:
  380. work_data->error = error;
  381. }
  382. static int cs40l50_erase(struct input_dev *dev, int effect_id)
  383. {
  384. struct cs40l50_vibra *vib = input_get_drvdata(dev);
  385. struct cs40l50_work work_data;
  386. work_data.vib = vib;
  387. work_data.effect = &dev->ff->effects[effect_id];
  388. INIT_WORK_ONSTACK(&work_data.work, cs40l50_erase_worker);
  389. /* Push to workqueue to serialize with playbacks */
  390. queue_work(vib->vib_wq, &work_data.work);
  391. flush_work(&work_data.work);
  392. destroy_work_on_stack(&work_data.work);
  393. return work_data.error;
  394. }
  395. static void cs40l50_remove_wq(void *data)
  396. {
  397. destroy_workqueue(data);
  398. }
  399. static int cs40l50_vibra_probe(struct platform_device *pdev)
  400. {
  401. struct cs40l50 *cs40l50 = dev_get_drvdata(pdev->dev.parent);
  402. struct cs40l50_vibra *vib;
  403. int error;
  404. vib = devm_kzalloc(pdev->dev.parent, sizeof(*vib), GFP_KERNEL);
  405. if (!vib)
  406. return -ENOMEM;
  407. vib->dev = cs40l50->dev;
  408. vib->regmap = cs40l50->regmap;
  409. vib->dsp = cs40l50_dsp;
  410. vib->input = devm_input_allocate_device(vib->dev);
  411. if (!vib->input)
  412. return -ENOMEM;
  413. vib->input->id.product = cs40l50->devid;
  414. vib->input->id.version = cs40l50->revid;
  415. vib->input->name = "cs40l50_vibra";
  416. input_set_drvdata(vib->input, vib);
  417. input_set_capability(vib->input, EV_FF, FF_PERIODIC);
  418. input_set_capability(vib->input, EV_FF, FF_CUSTOM);
  419. error = input_ff_create(vib->input, CS40L50_EFFECTS_MAX);
  420. if (error) {
  421. dev_err(vib->dev, "Failed to create input device\n");
  422. return error;
  423. }
  424. vib->input->ff->upload = cs40l50_add;
  425. vib->input->ff->playback = cs40l50_playback;
  426. vib->input->ff->erase = cs40l50_erase;
  427. INIT_LIST_HEAD(&vib->effect_head);
  428. vib->vib_wq = alloc_ordered_workqueue("vib_wq", WQ_HIGHPRI);
  429. if (!vib->vib_wq)
  430. return -ENOMEM;
  431. error = devm_add_action_or_reset(vib->dev, cs40l50_remove_wq, vib->vib_wq);
  432. if (error)
  433. return error;
  434. error = input_register_device(vib->input);
  435. if (error)
  436. return error;
  437. return 0;
  438. }
  439. static const struct platform_device_id cs40l50_vibra_id_match[] = {
  440. { "cs40l50-vibra", },
  441. {}
  442. };
  443. MODULE_DEVICE_TABLE(platform, cs40l50_vibra_id_match);
  444. static struct platform_driver cs40l50_vibra_driver = {
  445. .probe = cs40l50_vibra_probe,
  446. .id_table = cs40l50_vibra_id_match,
  447. .driver = {
  448. .name = "cs40l50-vibra",
  449. },
  450. };
  451. module_platform_driver(cs40l50_vibra_driver);
  452. MODULE_DESCRIPTION("CS40L50 Advanced Haptic Driver");
  453. MODULE_AUTHOR("James Ogletree, Cirrus Logic Inc. <james.ogletree@cirrus.com>");
  454. MODULE_LICENSE("GPL");