ctsrc.c 19 KB

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