ddbridge-ci.c 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377
  1. // SPDX-License-Identifier: GPL-2.0
  2. /*
  3. * ddbridge-ci.c: Digital Devices bridge CI (DuoFlex, CI Bridge) support
  4. *
  5. * Copyright (C) 2010-2017 Digital Devices GmbH
  6. * Marcus Metzler <[email protected]>
  7. * Ralph Metzler <[email protected]>
  8. */
  9. #include "ddbridge.h"
  10. #include "ddbridge-regs.h"
  11. #include "ddbridge-ci.h"
  12. #include "ddbridge-io.h"
  13. #include "ddbridge-i2c.h"
  14. #include "cxd2099.h"
  15. /* Octopus CI internal CI interface */
  16. static int wait_ci_ready(struct ddb_ci *ci)
  17. {
  18. u32 count = 10;
  19. ndelay(500);
  20. do {
  21. if (ddbreadl(ci->port->dev,
  22. CI_CONTROL(ci->nr)) & CI_READY)
  23. break;
  24. usleep_range(1, 2);
  25. if ((--count) == 0)
  26. return -1;
  27. } while (1);
  28. return 0;
  29. }
  30. static int read_attribute_mem(struct dvb_ca_en50221 *ca,
  31. int slot, int address)
  32. {
  33. struct ddb_ci *ci = ca->data;
  34. u32 val, off = (address >> 1) & (CI_BUFFER_SIZE - 1);
  35. if (address > CI_BUFFER_SIZE)
  36. return -1;
  37. ddbwritel(ci->port->dev, CI_READ_CMD | (1 << 16) | address,
  38. CI_DO_READ_ATTRIBUTES(ci->nr));
  39. wait_ci_ready(ci);
  40. val = 0xff & ddbreadl(ci->port->dev, CI_BUFFER(ci->nr) + off);
  41. return val;
  42. }
  43. static int write_attribute_mem(struct dvb_ca_en50221 *ca, int slot,
  44. int address, u8 value)
  45. {
  46. struct ddb_ci *ci = ca->data;
  47. ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
  48. CI_DO_ATTRIBUTE_RW(ci->nr));
  49. wait_ci_ready(ci);
  50. return 0;
  51. }
  52. static int read_cam_control(struct dvb_ca_en50221 *ca,
  53. int slot, u8 address)
  54. {
  55. u32 count = 100;
  56. struct ddb_ci *ci = ca->data;
  57. u32 res;
  58. ddbwritel(ci->port->dev, CI_READ_CMD | address,
  59. CI_DO_IO_RW(ci->nr));
  60. ndelay(500);
  61. do {
  62. res = ddbreadl(ci->port->dev, CI_READDATA(ci->nr));
  63. if (res & CI_READY)
  64. break;
  65. usleep_range(1, 2);
  66. if ((--count) == 0)
  67. return -1;
  68. } while (1);
  69. return 0xff & res;
  70. }
  71. static int write_cam_control(struct dvb_ca_en50221 *ca, int slot,
  72. u8 address, u8 value)
  73. {
  74. struct ddb_ci *ci = ca->data;
  75. ddbwritel(ci->port->dev, CI_WRITE_CMD | (value << 16) | address,
  76. CI_DO_IO_RW(ci->nr));
  77. wait_ci_ready(ci);
  78. return 0;
  79. }
  80. static int slot_reset(struct dvb_ca_en50221 *ca, int slot)
  81. {
  82. struct ddb_ci *ci = ca->data;
  83. ddbwritel(ci->port->dev, CI_POWER_ON,
  84. CI_CONTROL(ci->nr));
  85. msleep(100);
  86. ddbwritel(ci->port->dev, CI_POWER_ON | CI_RESET_CAM,
  87. CI_CONTROL(ci->nr));
  88. ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON | CI_RESET_CAM,
  89. CI_CONTROL(ci->nr));
  90. usleep_range(20, 25);
  91. ddbwritel(ci->port->dev, CI_ENABLE | CI_POWER_ON,
  92. CI_CONTROL(ci->nr));
  93. return 0;
  94. }
  95. static int slot_shutdown(struct dvb_ca_en50221 *ca, int slot)
  96. {
  97. struct ddb_ci *ci = ca->data;
  98. ddbwritel(ci->port->dev, 0, CI_CONTROL(ci->nr));
  99. msleep(300);
  100. return 0;
  101. }
  102. static int slot_ts_enable(struct dvb_ca_en50221 *ca, int slot)
  103. {
  104. struct ddb_ci *ci = ca->data;
  105. u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
  106. ddbwritel(ci->port->dev, val | CI_BYPASS_DISABLE,
  107. CI_CONTROL(ci->nr));
  108. return 0;
  109. }
  110. static int poll_slot_status(struct dvb_ca_en50221 *ca, int slot, int open)
  111. {
  112. struct ddb_ci *ci = ca->data;
  113. u32 val = ddbreadl(ci->port->dev, CI_CONTROL(ci->nr));
  114. int stat = 0;
  115. if (val & CI_CAM_DETECT)
  116. stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
  117. if (val & CI_CAM_READY)
  118. stat |= DVB_CA_EN50221_POLL_CAM_READY;
  119. return stat;
  120. }
  121. static struct dvb_ca_en50221 en_templ = {
  122. .read_attribute_mem = read_attribute_mem,
  123. .write_attribute_mem = write_attribute_mem,
  124. .read_cam_control = read_cam_control,
  125. .write_cam_control = write_cam_control,
  126. .slot_reset = slot_reset,
  127. .slot_shutdown = slot_shutdown,
  128. .slot_ts_enable = slot_ts_enable,
  129. .poll_slot_status = poll_slot_status,
  130. };
  131. static void ci_attach(struct ddb_port *port)
  132. {
  133. struct ddb_ci *ci;
  134. ci = kzalloc(sizeof(*ci), GFP_KERNEL);
  135. if (!ci)
  136. return;
  137. memcpy(&ci->en, &en_templ, sizeof(en_templ));
  138. ci->en.data = ci;
  139. port->en = &ci->en;
  140. port->en_freedata = 1;
  141. ci->port = port;
  142. ci->nr = port->nr - 2;
  143. }
  144. /* DuoFlex Dual CI support */
  145. static int write_creg(struct ddb_ci *ci, u8 data, u8 mask)
  146. {
  147. struct i2c_adapter *i2c = &ci->port->i2c->adap;
  148. u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
  149. ci->port->creg = (ci->port->creg & ~mask) | data;
  150. return i2c_write_reg(i2c, adr, 0x02, ci->port->creg);
  151. }
  152. static int read_attribute_mem_xo2(struct dvb_ca_en50221 *ca,
  153. int slot, int address)
  154. {
  155. struct ddb_ci *ci = ca->data;
  156. struct i2c_adapter *i2c = &ci->port->i2c->adap;
  157. u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
  158. int res;
  159. u8 val;
  160. res = i2c_read_reg16(i2c, adr, 0x8000 | address, &val);
  161. return res ? res : val;
  162. }
  163. static int write_attribute_mem_xo2(struct dvb_ca_en50221 *ca, int slot,
  164. int address, u8 value)
  165. {
  166. struct ddb_ci *ci = ca->data;
  167. struct i2c_adapter *i2c = &ci->port->i2c->adap;
  168. u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
  169. return i2c_write_reg16(i2c, adr, 0x8000 | address, value);
  170. }
  171. static int read_cam_control_xo2(struct dvb_ca_en50221 *ca,
  172. int slot, u8 address)
  173. {
  174. struct ddb_ci *ci = ca->data;
  175. struct i2c_adapter *i2c = &ci->port->i2c->adap;
  176. u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
  177. u8 val;
  178. int res;
  179. res = i2c_read_reg(i2c, adr, 0x20 | (address & 3), &val);
  180. return res ? res : val;
  181. }
  182. static int write_cam_control_xo2(struct dvb_ca_en50221 *ca, int slot,
  183. u8 address, u8 value)
  184. {
  185. struct ddb_ci *ci = ca->data;
  186. struct i2c_adapter *i2c = &ci->port->i2c->adap;
  187. u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
  188. return i2c_write_reg(i2c, adr, 0x20 | (address & 3), value);
  189. }
  190. static int slot_reset_xo2(struct dvb_ca_en50221 *ca, int slot)
  191. {
  192. struct ddb_ci *ci = ca->data;
  193. dev_dbg(ci->port->dev->dev, "%s\n", __func__);
  194. write_creg(ci, 0x01, 0x01);
  195. write_creg(ci, 0x04, 0x04);
  196. msleep(20);
  197. write_creg(ci, 0x02, 0x02);
  198. write_creg(ci, 0x00, 0x04);
  199. write_creg(ci, 0x18, 0x18);
  200. return 0;
  201. }
  202. static int slot_shutdown_xo2(struct dvb_ca_en50221 *ca, int slot)
  203. {
  204. struct ddb_ci *ci = ca->data;
  205. dev_dbg(ci->port->dev->dev, "%s\n", __func__);
  206. write_creg(ci, 0x10, 0xff);
  207. write_creg(ci, 0x08, 0x08);
  208. return 0;
  209. }
  210. static int slot_ts_enable_xo2(struct dvb_ca_en50221 *ca, int slot)
  211. {
  212. struct ddb_ci *ci = ca->data;
  213. dev_dbg(ci->port->dev->dev, "%s\n", __func__);
  214. write_creg(ci, 0x00, 0x10);
  215. return 0;
  216. }
  217. static int poll_slot_status_xo2(struct dvb_ca_en50221 *ca, int slot, int open)
  218. {
  219. struct ddb_ci *ci = ca->data;
  220. struct i2c_adapter *i2c = &ci->port->i2c->adap;
  221. u8 adr = (ci->port->type == DDB_CI_EXTERNAL_XO2) ? 0x12 : 0x13;
  222. u8 val = 0;
  223. int stat = 0;
  224. i2c_read_reg(i2c, adr, 0x01, &val);
  225. if (val & 2)
  226. stat |= DVB_CA_EN50221_POLL_CAM_PRESENT;
  227. if (val & 1)
  228. stat |= DVB_CA_EN50221_POLL_CAM_READY;
  229. return stat;
  230. }
  231. static struct dvb_ca_en50221 en_xo2_templ = {
  232. .read_attribute_mem = read_attribute_mem_xo2,
  233. .write_attribute_mem = write_attribute_mem_xo2,
  234. .read_cam_control = read_cam_control_xo2,
  235. .write_cam_control = write_cam_control_xo2,
  236. .slot_reset = slot_reset_xo2,
  237. .slot_shutdown = slot_shutdown_xo2,
  238. .slot_ts_enable = slot_ts_enable_xo2,
  239. .poll_slot_status = poll_slot_status_xo2,
  240. };
  241. static void ci_xo2_attach(struct ddb_port *port)
  242. {
  243. struct ddb_ci *ci;
  244. ci = kzalloc(sizeof(*ci), GFP_KERNEL);
  245. if (!ci)
  246. return;
  247. memcpy(&ci->en, &en_xo2_templ, sizeof(en_xo2_templ));
  248. ci->en.data = ci;
  249. port->en = &ci->en;
  250. port->en_freedata = 1;
  251. ci->port = port;
  252. ci->nr = port->nr - 2;
  253. ci->port->creg = 0;
  254. write_creg(ci, 0x10, 0xff);
  255. write_creg(ci, 0x08, 0x08);
  256. }
  257. static const struct cxd2099_cfg cxd_cfgtmpl = {
  258. .bitrate = 72000,
  259. .polarity = 1,
  260. .clock_mode = 1,
  261. .max_i2c = 512,
  262. };
  263. static int ci_cxd2099_attach(struct ddb_port *port, u32 bitrate)
  264. {
  265. struct cxd2099_cfg cxd_cfg = cxd_cfgtmpl;
  266. struct i2c_client *client;
  267. cxd_cfg.bitrate = bitrate;
  268. cxd_cfg.en = &port->en;
  269. client = dvb_module_probe("cxd2099", NULL, &port->i2c->adap,
  270. 0x40, &cxd_cfg);
  271. if (!client)
  272. goto err;
  273. port->dvb[0].i2c_client[0] = client;
  274. port->en_freedata = 0;
  275. return 0;
  276. err:
  277. dev_err(port->dev->dev, "CXD2099AR attach failed\n");
  278. return -ENODEV;
  279. }
  280. int ddb_ci_attach(struct ddb_port *port, u32 bitrate)
  281. {
  282. int ret;
  283. switch (port->type) {
  284. case DDB_CI_EXTERNAL_SONY:
  285. ret = ci_cxd2099_attach(port, bitrate);
  286. if (ret)
  287. return -ENODEV;
  288. break;
  289. case DDB_CI_EXTERNAL_XO2:
  290. case DDB_CI_EXTERNAL_XO2_B:
  291. ci_xo2_attach(port);
  292. break;
  293. case DDB_CI_INTERNAL:
  294. ci_attach(port);
  295. break;
  296. default:
  297. return -ENODEV;
  298. }
  299. if (!port->en)
  300. return -ENODEV;
  301. dvb_ca_en50221_init(port->dvb[0].adap, port->en, 0, 1);
  302. return 0;
  303. }
  304. void ddb_ci_detach(struct ddb_port *port)
  305. {
  306. if (port->dvb[0].dev)
  307. dvb_unregister_device(port->dvb[0].dev);
  308. if (port->en) {
  309. dvb_ca_en50221_release(port->en);
  310. dvb_module_release(port->dvb[0].i2c_client[0]);
  311. port->dvb[0].i2c_client[0] = NULL;
  312. /* free alloc'ed memory if needed */
  313. if (port->en_freedata)
  314. kfree(port->en->data);
  315. port->en = NULL;
  316. }
  317. }