ctsrc.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2008, Creative Technology Ltd. All Rights Reserved.
  4. *
  5. * @File ctsrc.c
  6. *
  7. * @Brief
  8. * This file contains the implementation of the Sample Rate Convertor
  9. * resource management object.
  10. *
  11. * @Author Liu Chun
  12. * @Date May 13 2008
  13. */
  14. #include "ctsrc.h"
  15. #include "cthardware.h"
  16. #include <linux/slab.h>
  17. #define SRC_RESOURCE_NUM 256
  18. #define SRCIMP_RESOURCE_NUM 256
  19. static unsigned int conj_mask;
  20. static int src_default_config_memrd(struct src *src);
  21. static int src_default_config_memwr(struct src *src);
  22. static int src_default_config_arcrw(struct src *src);
  23. static int (*src_default_config[3])(struct src *) = {
  24. [MEMRD] = src_default_config_memrd,
  25. [MEMWR] = src_default_config_memwr,
  26. [ARCRW] = src_default_config_arcrw
  27. };
  28. static int src_set_state(struct src *src, unsigned int state)
  29. {
  30. struct hw *hw;
  31. hw = src->rsc.hw;
  32. hw->src_set_state(src->rsc.ctrl_blk, state);
  33. return 0;
  34. }
  35. static int src_set_bm(struct src *src, unsigned int bm)
  36. {
  37. struct hw *hw;
  38. hw = src->rsc.hw;
  39. hw->src_set_bm(src->rsc.ctrl_blk, bm);
  40. return 0;
  41. }
  42. static int src_set_sf(struct src *src, unsigned int sf)
  43. {
  44. struct hw *hw;
  45. hw = src->rsc.hw;
  46. hw->src_set_sf(src->rsc.ctrl_blk, sf);
  47. return 0;
  48. }
  49. static int src_set_pm(struct src *src, unsigned int pm)
  50. {
  51. struct hw *hw;
  52. hw = src->rsc.hw;
  53. hw->src_set_pm(src->rsc.ctrl_blk, pm);
  54. return 0;
  55. }
  56. static int src_set_rom(struct src *src, unsigned int rom)
  57. {
  58. struct hw *hw;
  59. hw = src->rsc.hw;
  60. hw->src_set_rom(src->rsc.ctrl_blk, rom);
  61. return 0;
  62. }
  63. static int src_set_vo(struct src *src, unsigned int vo)
  64. {
  65. struct hw *hw;
  66. hw = src->rsc.hw;
  67. hw->src_set_vo(src->rsc.ctrl_blk, vo);
  68. return 0;
  69. }
  70. static int src_set_st(struct src *src, unsigned int st)
  71. {
  72. struct hw *hw;
  73. hw = src->rsc.hw;
  74. hw->src_set_st(src->rsc.ctrl_blk, st);
  75. return 0;
  76. }
  77. static int src_set_bp(struct src *src, unsigned int bp)
  78. {
  79. struct hw *hw;
  80. hw = src->rsc.hw;
  81. hw->src_set_bp(src->rsc.ctrl_blk, bp);
  82. return 0;
  83. }
  84. static int src_set_cisz(struct src *src, unsigned int cisz)
  85. {
  86. struct hw *hw;
  87. hw = src->rsc.hw;
  88. hw->src_set_cisz(src->rsc.ctrl_blk, cisz);
  89. return 0;
  90. }
  91. static int src_set_ca(struct src *src, unsigned int ca)
  92. {
  93. struct hw *hw;
  94. hw = src->rsc.hw;
  95. hw->src_set_ca(src->rsc.ctrl_blk, ca);
  96. return 0;
  97. }
  98. static int src_set_sa(struct src *src, unsigned int sa)
  99. {
  100. struct hw *hw;
  101. hw = src->rsc.hw;
  102. hw->src_set_sa(src->rsc.ctrl_blk, sa);
  103. return 0;
  104. }
  105. static int src_set_la(struct src *src, unsigned int la)
  106. {
  107. struct hw *hw;
  108. hw = src->rsc.hw;
  109. hw->src_set_la(src->rsc.ctrl_blk, la);
  110. return 0;
  111. }
  112. static int src_set_pitch(struct src *src, unsigned int pitch)
  113. {
  114. struct hw *hw;
  115. hw = src->rsc.hw;
  116. hw->src_set_pitch(src->rsc.ctrl_blk, pitch);
  117. return 0;
  118. }
  119. static int src_set_clear_zbufs(struct src *src)
  120. {
  121. struct hw *hw;
  122. hw = src->rsc.hw;
  123. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  124. return 0;
  125. }
  126. static int src_commit_write(struct src *src)
  127. {
  128. struct hw *hw;
  129. int i;
  130. unsigned int dirty = 0;
  131. hw = src->rsc.hw;
  132. src->rsc.ops->master(&src->rsc);
  133. if (src->rsc.msr > 1) {
  134. /* Save dirty flags for conjugate resource programming */
  135. dirty = hw->src_get_dirty(src->rsc.ctrl_blk) & conj_mask;
  136. }
  137. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  138. src->rsc.ctrl_blk);
  139. /* Program conjugate parameter mixer resources */
  140. if (MEMWR == src->mode)
  141. return 0;
  142. for (i = 1; i < src->rsc.msr; i++) {
  143. src->rsc.ops->next_conj(&src->rsc);
  144. hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
  145. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  146. src->rsc.ctrl_blk);
  147. }
  148. src->rsc.ops->master(&src->rsc);
  149. return 0;
  150. }
  151. static int src_get_ca(struct src *src)
  152. {
  153. struct hw *hw;
  154. hw = src->rsc.hw;
  155. return hw->src_get_ca(hw, src->rsc.ops->index(&src->rsc),
  156. src->rsc.ctrl_blk);
  157. }
  158. static int src_init(struct src *src)
  159. {
  160. src_default_config[src->mode](src);
  161. return 0;
  162. }
  163. static struct src *src_next_interleave(struct src *src)
  164. {
  165. return src->intlv;
  166. }
  167. static int src_default_config_memrd(struct src *src)
  168. {
  169. struct hw *hw = src->rsc.hw;
  170. unsigned int rsr, msr;
  171. hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
  172. hw->src_set_bm(src->rsc.ctrl_blk, 1);
  173. for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
  174. rsr++;
  175. hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
  176. hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
  177. hw->src_set_wr(src->rsc.ctrl_blk, 0);
  178. hw->src_set_pm(src->rsc.ctrl_blk, 0);
  179. hw->src_set_rom(src->rsc.ctrl_blk, 0);
  180. hw->src_set_vo(src->rsc.ctrl_blk, 0);
  181. hw->src_set_st(src->rsc.ctrl_blk, 0);
  182. hw->src_set_ilsz(src->rsc.ctrl_blk, src->multi - 1);
  183. hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
  184. hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
  185. hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
  186. hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
  187. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  188. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  189. src->rsc.ops->master(&src->rsc);
  190. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  191. src->rsc.ctrl_blk);
  192. for (msr = 1; msr < src->rsc.msr; msr++) {
  193. src->rsc.ops->next_conj(&src->rsc);
  194. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  195. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  196. src->rsc.ctrl_blk);
  197. }
  198. src->rsc.ops->master(&src->rsc);
  199. return 0;
  200. }
  201. static int src_default_config_memwr(struct src *src)
  202. {
  203. struct hw *hw = src->rsc.hw;
  204. hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
  205. hw->src_set_bm(src->rsc.ctrl_blk, 1);
  206. hw->src_set_rsr(src->rsc.ctrl_blk, 0);
  207. hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_S16);
  208. hw->src_set_wr(src->rsc.ctrl_blk, 1);
  209. hw->src_set_pm(src->rsc.ctrl_blk, 0);
  210. hw->src_set_rom(src->rsc.ctrl_blk, 0);
  211. hw->src_set_vo(src->rsc.ctrl_blk, 0);
  212. hw->src_set_st(src->rsc.ctrl_blk, 0);
  213. hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
  214. hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
  215. hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
  216. hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
  217. hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
  218. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  219. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  220. src->rsc.ops->master(&src->rsc);
  221. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  222. src->rsc.ctrl_blk);
  223. return 0;
  224. }
  225. static int src_default_config_arcrw(struct src *src)
  226. {
  227. struct hw *hw = src->rsc.hw;
  228. unsigned int rsr, msr;
  229. unsigned int dirty;
  230. hw->src_set_state(src->rsc.ctrl_blk, SRC_STATE_OFF);
  231. hw->src_set_bm(src->rsc.ctrl_blk, 0);
  232. for (rsr = 0, msr = src->rsc.msr; msr > 1; msr >>= 1)
  233. rsr++;
  234. hw->src_set_rsr(src->rsc.ctrl_blk, rsr);
  235. hw->src_set_sf(src->rsc.ctrl_blk, SRC_SF_F32);
  236. hw->src_set_wr(src->rsc.ctrl_blk, 0);
  237. hw->src_set_pm(src->rsc.ctrl_blk, 0);
  238. hw->src_set_rom(src->rsc.ctrl_blk, 0);
  239. hw->src_set_vo(src->rsc.ctrl_blk, 0);
  240. hw->src_set_st(src->rsc.ctrl_blk, 0);
  241. hw->src_set_ilsz(src->rsc.ctrl_blk, 0);
  242. hw->src_set_cisz(src->rsc.ctrl_blk, 0x80);
  243. hw->src_set_sa(src->rsc.ctrl_blk, 0x0);
  244. /*hw->src_set_sa(src->rsc.ctrl_blk, 0x100);*/
  245. hw->src_set_la(src->rsc.ctrl_blk, 0x1000);
  246. /*hw->src_set_la(src->rsc.ctrl_blk, 0x03ffffe0);*/
  247. hw->src_set_ca(src->rsc.ctrl_blk, 0x80);
  248. hw->src_set_pitch(src->rsc.ctrl_blk, 0x1000000);
  249. hw->src_set_clear_zbufs(src->rsc.ctrl_blk, 1);
  250. dirty = hw->src_get_dirty(src->rsc.ctrl_blk);
  251. src->rsc.ops->master(&src->rsc);
  252. for (msr = 0; msr < src->rsc.msr; msr++) {
  253. hw->src_set_dirty(src->rsc.ctrl_blk, dirty);
  254. hw->src_commit_write(hw, src->rsc.ops->index(&src->rsc),
  255. src->rsc.ctrl_blk);
  256. src->rsc.ops->next_conj(&src->rsc);
  257. }
  258. src->rsc.ops->master(&src->rsc);
  259. return 0;
  260. }
  261. static const struct src_rsc_ops src_rsc_ops = {
  262. .set_state = src_set_state,
  263. .set_bm = src_set_bm,
  264. .set_sf = src_set_sf,
  265. .set_pm = src_set_pm,
  266. .set_rom = src_set_rom,
  267. .set_vo = src_set_vo,
  268. .set_st = src_set_st,
  269. .set_bp = src_set_bp,
  270. .set_cisz = src_set_cisz,
  271. .set_ca = src_set_ca,
  272. .set_sa = src_set_sa,
  273. .set_la = src_set_la,
  274. .set_pitch = src_set_pitch,
  275. .set_clr_zbufs = src_set_clear_zbufs,
  276. .commit_write = src_commit_write,
  277. .get_ca = src_get_ca,
  278. .init = src_init,
  279. .next_interleave = src_next_interleave,
  280. };
  281. static int
  282. src_rsc_init(struct src *src, u32 idx,
  283. const struct src_desc *desc, struct src_mgr *mgr)
  284. {
  285. int err;
  286. int i, n;
  287. struct src *p;
  288. n = (MEMRD == desc->mode) ? desc->multi : 1;
  289. for (i = 0, p = src; i < n; i++, p++) {
  290. err = rsc_init(&p->rsc, idx + i, SRC, desc->msr, mgr->mgr.hw);
  291. if (err)
  292. goto error1;
  293. /* Initialize src specific rsc operations */
  294. p->ops = &src_rsc_ops;
  295. p->multi = (0 == i) ? desc->multi : 1;
  296. p->mode = desc->mode;
  297. src_default_config[desc->mode](p);
  298. mgr->src_enable(mgr, p);
  299. p->intlv = p + 1;
  300. }
  301. (--p)->intlv = NULL; /* Set @intlv of the last SRC to NULL */
  302. mgr->commit_write(mgr);
  303. return 0;
  304. error1:
  305. for (i--, p--; i >= 0; i--, p--) {
  306. mgr->src_disable(mgr, p);
  307. rsc_uninit(&p->rsc);
  308. }
  309. mgr->commit_write(mgr);
  310. return err;
  311. }
  312. static int src_rsc_uninit(struct src *src, struct src_mgr *mgr)
  313. {
  314. int i, n;
  315. struct src *p;
  316. n = (MEMRD == src->mode) ? src->multi : 1;
  317. for (i = 0, p = src; i < n; i++, p++) {
  318. mgr->src_disable(mgr, p);
  319. rsc_uninit(&p->rsc);
  320. p->multi = 0;
  321. p->ops = NULL;
  322. p->mode = NUM_SRCMODES;
  323. p->intlv = NULL;
  324. }
  325. mgr->commit_write(mgr);
  326. return 0;
  327. }
  328. static int
  329. get_src_rsc(struct src_mgr *mgr, const struct src_desc *desc, struct src **rsrc)
  330. {
  331. unsigned int idx = SRC_RESOURCE_NUM;
  332. int err;
  333. struct src *src;
  334. unsigned long flags;
  335. *rsrc = NULL;
  336. /* Check whether there are sufficient src resources to meet request. */
  337. spin_lock_irqsave(&mgr->mgr_lock, flags);
  338. if (MEMRD == desc->mode)
  339. err = mgr_get_resource(&mgr->mgr, desc->multi, &idx);
  340. else
  341. err = mgr_get_resource(&mgr->mgr, 1, &idx);
  342. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  343. if (err) {
  344. dev_err(mgr->card->dev,
  345. "Can't meet SRC resource request!\n");
  346. return err;
  347. }
  348. /* Allocate mem for master src resource */
  349. if (MEMRD == desc->mode)
  350. src = kcalloc(desc->multi, sizeof(*src), GFP_KERNEL);
  351. else
  352. src = kzalloc(sizeof(*src), GFP_KERNEL);
  353. if (!src) {
  354. err = -ENOMEM;
  355. goto error1;
  356. }
  357. err = src_rsc_init(src, idx, desc, mgr);
  358. if (err)
  359. goto error2;
  360. *rsrc = src;
  361. return 0;
  362. error2:
  363. kfree(src);
  364. error1:
  365. spin_lock_irqsave(&mgr->mgr_lock, flags);
  366. if (MEMRD == desc->mode)
  367. mgr_put_resource(&mgr->mgr, desc->multi, idx);
  368. else
  369. mgr_put_resource(&mgr->mgr, 1, idx);
  370. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  371. return err;
  372. }
  373. static int put_src_rsc(struct src_mgr *mgr, struct src *src)
  374. {
  375. unsigned long flags;
  376. spin_lock_irqsave(&mgr->mgr_lock, flags);
  377. src->rsc.ops->master(&src->rsc);
  378. if (MEMRD == src->mode)
  379. mgr_put_resource(&mgr->mgr, src->multi,
  380. src->rsc.ops->index(&src->rsc));
  381. else
  382. mgr_put_resource(&mgr->mgr, 1, src->rsc.ops->index(&src->rsc));
  383. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  384. src_rsc_uninit(src, mgr);
  385. kfree(src);
  386. return 0;
  387. }
  388. static int src_enable_s(struct src_mgr *mgr, struct src *src)
  389. {
  390. struct hw *hw = mgr->mgr.hw;
  391. int i;
  392. src->rsc.ops->master(&src->rsc);
  393. for (i = 0; i < src->rsc.msr; i++) {
  394. hw->src_mgr_enbs_src(mgr->mgr.ctrl_blk,
  395. src->rsc.ops->index(&src->rsc));
  396. src->rsc.ops->next_conj(&src->rsc);
  397. }
  398. src->rsc.ops->master(&src->rsc);
  399. return 0;
  400. }
  401. static int src_enable(struct src_mgr *mgr, struct src *src)
  402. {
  403. struct hw *hw = mgr->mgr.hw;
  404. int i;
  405. src->rsc.ops->master(&src->rsc);
  406. for (i = 0; i < src->rsc.msr; i++) {
  407. hw->src_mgr_enb_src(mgr->mgr.ctrl_blk,
  408. src->rsc.ops->index(&src->rsc));
  409. src->rsc.ops->next_conj(&src->rsc);
  410. }
  411. src->rsc.ops->master(&src->rsc);
  412. return 0;
  413. }
  414. static int src_disable(struct src_mgr *mgr, struct src *src)
  415. {
  416. struct hw *hw = mgr->mgr.hw;
  417. int i;
  418. src->rsc.ops->master(&src->rsc);
  419. for (i = 0; i < src->rsc.msr; i++) {
  420. hw->src_mgr_dsb_src(mgr->mgr.ctrl_blk,
  421. src->rsc.ops->index(&src->rsc));
  422. src->rsc.ops->next_conj(&src->rsc);
  423. }
  424. src->rsc.ops->master(&src->rsc);
  425. return 0;
  426. }
  427. static int src_mgr_commit_write(struct src_mgr *mgr)
  428. {
  429. struct hw *hw = mgr->mgr.hw;
  430. hw->src_mgr_commit_write(hw, mgr->mgr.ctrl_blk);
  431. return 0;
  432. }
  433. int src_mgr_create(struct hw *hw, struct src_mgr **rsrc_mgr)
  434. {
  435. int err, i;
  436. struct src_mgr *src_mgr;
  437. *rsrc_mgr = NULL;
  438. src_mgr = kzalloc(sizeof(*src_mgr), GFP_KERNEL);
  439. if (!src_mgr)
  440. return -ENOMEM;
  441. err = rsc_mgr_init(&src_mgr->mgr, SRC, SRC_RESOURCE_NUM, hw);
  442. if (err)
  443. goto error1;
  444. spin_lock_init(&src_mgr->mgr_lock);
  445. conj_mask = hw->src_dirty_conj_mask();
  446. src_mgr->get_src = get_src_rsc;
  447. src_mgr->put_src = put_src_rsc;
  448. src_mgr->src_enable_s = src_enable_s;
  449. src_mgr->src_enable = src_enable;
  450. src_mgr->src_disable = src_disable;
  451. src_mgr->commit_write = src_mgr_commit_write;
  452. src_mgr->card = hw->card;
  453. /* Disable all SRC resources. */
  454. for (i = 0; i < 256; i++)
  455. hw->src_mgr_dsb_src(src_mgr->mgr.ctrl_blk, i);
  456. hw->src_mgr_commit_write(hw, src_mgr->mgr.ctrl_blk);
  457. *rsrc_mgr = src_mgr;
  458. return 0;
  459. error1:
  460. kfree(src_mgr);
  461. return err;
  462. }
  463. int src_mgr_destroy(struct src_mgr *src_mgr)
  464. {
  465. rsc_mgr_uninit(&src_mgr->mgr);
  466. kfree(src_mgr);
  467. return 0;
  468. }
  469. /* SRCIMP resource manager operations */
  470. static void srcimp_master(struct rsc *rsc)
  471. {
  472. rsc->conj = 0;
  473. rsc->idx = container_of(rsc, struct srcimp, rsc)->idx[0];
  474. }
  475. static void srcimp_next_conj(struct rsc *rsc)
  476. {
  477. rsc->conj++;
  478. }
  479. static int srcimp_index(const struct rsc *rsc)
  480. {
  481. return container_of(rsc, struct srcimp, rsc)->idx[rsc->conj];
  482. }
  483. static const struct rsc_ops srcimp_basic_rsc_ops = {
  484. .master = srcimp_master,
  485. .next_conj = srcimp_next_conj,
  486. .index = srcimp_index,
  487. .output_slot = NULL,
  488. };
  489. static int srcimp_map(struct srcimp *srcimp, struct src *src, struct rsc *input)
  490. {
  491. struct imapper *entry;
  492. int i;
  493. srcimp->rsc.ops->master(&srcimp->rsc);
  494. src->rsc.ops->master(&src->rsc);
  495. input->ops->master(input);
  496. /* Program master and conjugate resources */
  497. for (i = 0; i < srcimp->rsc.msr; i++) {
  498. entry = &srcimp->imappers[i];
  499. entry->slot = input->ops->output_slot(input);
  500. entry->user = src->rsc.ops->index(&src->rsc);
  501. entry->addr = srcimp->rsc.ops->index(&srcimp->rsc);
  502. srcimp->mgr->imap_add(srcimp->mgr, entry);
  503. srcimp->mapped |= (0x1 << i);
  504. srcimp->rsc.ops->next_conj(&srcimp->rsc);
  505. input->ops->next_conj(input);
  506. }
  507. srcimp->rsc.ops->master(&srcimp->rsc);
  508. input->ops->master(input);
  509. return 0;
  510. }
  511. static int srcimp_unmap(struct srcimp *srcimp)
  512. {
  513. int i;
  514. /* Program master and conjugate resources */
  515. for (i = 0; i < srcimp->rsc.msr; i++) {
  516. if (srcimp->mapped & (0x1 << i)) {
  517. srcimp->mgr->imap_delete(srcimp->mgr,
  518. &srcimp->imappers[i]);
  519. srcimp->mapped &= ~(0x1 << i);
  520. }
  521. }
  522. return 0;
  523. }
  524. static const struct srcimp_rsc_ops srcimp_ops = {
  525. .map = srcimp_map,
  526. .unmap = srcimp_unmap
  527. };
  528. static int srcimp_rsc_init(struct srcimp *srcimp,
  529. const struct srcimp_desc *desc,
  530. struct srcimp_mgr *mgr)
  531. {
  532. int err;
  533. err = rsc_init(&srcimp->rsc, srcimp->idx[0],
  534. SRCIMP, desc->msr, mgr->mgr.hw);
  535. if (err)
  536. return err;
  537. /* Reserve memory for imapper nodes */
  538. srcimp->imappers = kcalloc(desc->msr, sizeof(struct imapper),
  539. GFP_KERNEL);
  540. if (!srcimp->imappers) {
  541. err = -ENOMEM;
  542. goto error1;
  543. }
  544. /* Set srcimp specific operations */
  545. srcimp->rsc.ops = &srcimp_basic_rsc_ops;
  546. srcimp->ops = &srcimp_ops;
  547. srcimp->mgr = mgr;
  548. srcimp->rsc.ops->master(&srcimp->rsc);
  549. return 0;
  550. error1:
  551. rsc_uninit(&srcimp->rsc);
  552. return err;
  553. }
  554. static int srcimp_rsc_uninit(struct srcimp *srcimp)
  555. {
  556. kfree(srcimp->imappers);
  557. srcimp->imappers = NULL;
  558. srcimp->ops = NULL;
  559. srcimp->mgr = NULL;
  560. rsc_uninit(&srcimp->rsc);
  561. return 0;
  562. }
  563. static int get_srcimp_rsc(struct srcimp_mgr *mgr,
  564. const struct srcimp_desc *desc,
  565. struct srcimp **rsrcimp)
  566. {
  567. int err, i;
  568. unsigned int idx;
  569. struct srcimp *srcimp;
  570. unsigned long flags;
  571. *rsrcimp = NULL;
  572. /* Allocate mem for SRCIMP resource */
  573. srcimp = kzalloc(sizeof(*srcimp), GFP_KERNEL);
  574. if (!srcimp)
  575. return -ENOMEM;
  576. /* Check whether there are sufficient SRCIMP resources. */
  577. err = 0;
  578. spin_lock_irqsave(&mgr->mgr_lock, flags);
  579. for (i = 0; i < desc->msr; i++) {
  580. err = mgr_get_resource(&mgr->mgr, 1, &idx);
  581. if (err)
  582. break;
  583. srcimp->idx[i] = idx;
  584. }
  585. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  586. if (err) {
  587. dev_err(mgr->card->dev,
  588. "Can't meet SRCIMP resource request!\n");
  589. goto error1;
  590. }
  591. err = srcimp_rsc_init(srcimp, desc, mgr);
  592. if (err)
  593. goto error1;
  594. *rsrcimp = srcimp;
  595. return 0;
  596. error1:
  597. spin_lock_irqsave(&mgr->mgr_lock, flags);
  598. for (i--; i >= 0; i--)
  599. mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
  600. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  601. kfree(srcimp);
  602. return err;
  603. }
  604. static int put_srcimp_rsc(struct srcimp_mgr *mgr, struct srcimp *srcimp)
  605. {
  606. unsigned long flags;
  607. int i;
  608. spin_lock_irqsave(&mgr->mgr_lock, flags);
  609. for (i = 0; i < srcimp->rsc.msr; i++)
  610. mgr_put_resource(&mgr->mgr, 1, srcimp->idx[i]);
  611. spin_unlock_irqrestore(&mgr->mgr_lock, flags);
  612. srcimp_rsc_uninit(srcimp);
  613. kfree(srcimp);
  614. return 0;
  615. }
  616. static int srcimp_map_op(void *data, struct imapper *entry)
  617. {
  618. struct rsc_mgr *mgr = &((struct srcimp_mgr *)data)->mgr;
  619. struct hw *hw = mgr->hw;
  620. hw->srcimp_mgr_set_imaparc(mgr->ctrl_blk, entry->slot);
  621. hw->srcimp_mgr_set_imapuser(mgr->ctrl_blk, entry->user);
  622. hw->srcimp_mgr_set_imapnxt(mgr->ctrl_blk, entry->next);
  623. hw->srcimp_mgr_set_imapaddr(mgr->ctrl_blk, entry->addr);
  624. hw->srcimp_mgr_commit_write(mgr->hw, mgr->ctrl_blk);
  625. return 0;
  626. }
  627. static int srcimp_imap_add(struct srcimp_mgr *mgr, struct imapper *entry)
  628. {
  629. unsigned long flags;
  630. int err;
  631. spin_lock_irqsave(&mgr->imap_lock, flags);
  632. if ((0 == entry->addr) && (mgr->init_imap_added)) {
  633. input_mapper_delete(&mgr->imappers,
  634. mgr->init_imap, srcimp_map_op, mgr);
  635. mgr->init_imap_added = 0;
  636. }
  637. err = input_mapper_add(&mgr->imappers, entry, srcimp_map_op, mgr);
  638. spin_unlock_irqrestore(&mgr->imap_lock, flags);
  639. return err;
  640. }
  641. static int srcimp_imap_delete(struct srcimp_mgr *mgr, struct imapper *entry)
  642. {
  643. unsigned long flags;
  644. int err;
  645. spin_lock_irqsave(&mgr->imap_lock, flags);
  646. err = input_mapper_delete(&mgr->imappers, entry, srcimp_map_op, mgr);
  647. if (list_empty(&mgr->imappers)) {
  648. input_mapper_add(&mgr->imappers, mgr->init_imap,
  649. srcimp_map_op, mgr);
  650. mgr->init_imap_added = 1;
  651. }
  652. spin_unlock_irqrestore(&mgr->imap_lock, flags);
  653. return err;
  654. }
  655. int srcimp_mgr_create(struct hw *hw, struct srcimp_mgr **rsrcimp_mgr)
  656. {
  657. int err;
  658. struct srcimp_mgr *srcimp_mgr;
  659. struct imapper *entry;
  660. *rsrcimp_mgr = NULL;
  661. srcimp_mgr = kzalloc(sizeof(*srcimp_mgr), GFP_KERNEL);
  662. if (!srcimp_mgr)
  663. return -ENOMEM;
  664. err = rsc_mgr_init(&srcimp_mgr->mgr, SRCIMP, SRCIMP_RESOURCE_NUM, hw);
  665. if (err)
  666. goto error1;
  667. spin_lock_init(&srcimp_mgr->mgr_lock);
  668. spin_lock_init(&srcimp_mgr->imap_lock);
  669. INIT_LIST_HEAD(&srcimp_mgr->imappers);
  670. entry = kzalloc(sizeof(*entry), GFP_KERNEL);
  671. if (!entry) {
  672. err = -ENOMEM;
  673. goto error2;
  674. }
  675. entry->slot = entry->addr = entry->next = entry->user = 0;
  676. list_add(&entry->list, &srcimp_mgr->imappers);
  677. srcimp_mgr->init_imap = entry;
  678. srcimp_mgr->init_imap_added = 1;
  679. srcimp_mgr->get_srcimp = get_srcimp_rsc;
  680. srcimp_mgr->put_srcimp = put_srcimp_rsc;
  681. srcimp_mgr->imap_add = srcimp_imap_add;
  682. srcimp_mgr->imap_delete = srcimp_imap_delete;
  683. srcimp_mgr->card = hw->card;
  684. *rsrcimp_mgr = srcimp_mgr;
  685. return 0;
  686. error2:
  687. rsc_mgr_uninit(&srcimp_mgr->mgr);
  688. error1:
  689. kfree(srcimp_mgr);
  690. return err;
  691. }
  692. int srcimp_mgr_destroy(struct srcimp_mgr *srcimp_mgr)
  693. {
  694. unsigned long flags;
  695. /* free src input mapper list */
  696. spin_lock_irqsave(&srcimp_mgr->imap_lock, flags);
  697. free_input_mapper_list(&srcimp_mgr->imappers);
  698. spin_unlock_irqrestore(&srcimp_mgr->imap_lock, flags);
  699. rsc_mgr_uninit(&srcimp_mgr->mgr);
  700. kfree(srcimp_mgr);
  701. return 0;
  702. }