sony-btf-mpx.c 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383
  1. // SPDX-License-Identifier: GPL-2.0-only
  2. /*
  3. * Copyright (C) 2005-2006 Micronas USA Inc.
  4. */
  5. #include <linux/module.h>
  6. #include <linux/init.h>
  7. #include <linux/i2c.h>
  8. #include <linux/videodev2.h>
  9. #include <media/tuner.h>
  10. #include <media/v4l2-common.h>
  11. #include <media/v4l2-ioctl.h>
  12. #include <media/v4l2-device.h>
  13. #include <linux/slab.h>
  14. MODULE_DESCRIPTION("sony-btf-mpx driver");
  15. MODULE_LICENSE("GPL v2");
  16. static int debug;
  17. module_param(debug, int, 0644);
  18. MODULE_PARM_DESC(debug, "debug level 0=off(default) 1=on");
  19. /* #define MPX_DEBUG */
  20. /*
  21. * Note:
  22. *
  23. * AS(IF/MPX) pin: LOW HIGH/OPEN
  24. * IF/MPX address: 0x42/0x40 0x43/0x44
  25. */
  26. static int force_mpx_mode = -1;
  27. module_param(force_mpx_mode, int, 0644);
  28. struct sony_btf_mpx {
  29. struct v4l2_subdev sd;
  30. int mpxmode;
  31. u32 audmode;
  32. };
  33. static inline struct sony_btf_mpx *to_state(struct v4l2_subdev *sd)
  34. {
  35. return container_of(sd, struct sony_btf_mpx, sd);
  36. }
  37. static int mpx_write(struct i2c_client *client, int dev, int addr, int val)
  38. {
  39. u8 buffer[5];
  40. struct i2c_msg msg;
  41. buffer[0] = dev;
  42. buffer[1] = addr >> 8;
  43. buffer[2] = addr & 0xff;
  44. buffer[3] = val >> 8;
  45. buffer[4] = val & 0xff;
  46. msg.addr = client->addr;
  47. msg.flags = 0;
  48. msg.len = 5;
  49. msg.buf = buffer;
  50. i2c_transfer(client->adapter, &msg, 1);
  51. return 0;
  52. }
  53. /*
  54. * MPX register values for the BTF-PG472Z:
  55. *
  56. * FM_ NICAM_ SCART_
  57. * MODUS SOURCE ACB PRESCAL PRESCAL PRESCAL SYSTEM VOLUME
  58. * 10/0030 12/0008 12/0013 12/000E 12/0010 12/0000 10/0020 12/0000
  59. * ---------------------------------------------------------------
  60. * Auto 1003 0020 0100 2603 5000 XXXX 0001 7500
  61. *
  62. * B/G
  63. * Mono 1003 0020 0100 2603 5000 XXXX 0003 7500
  64. * A2 1003 0020 0100 2601 5000 XXXX 0003 7500
  65. * NICAM 1003 0120 0100 2603 5000 XXXX 0008 7500
  66. *
  67. * I
  68. * Mono 1003 0020 0100 2603 7900 XXXX 000A 7500
  69. * NICAM 1003 0120 0100 2603 7900 XXXX 000A 7500
  70. *
  71. * D/K
  72. * Mono 1003 0020 0100 2603 5000 XXXX 0004 7500
  73. * A2-1 1003 0020 0100 2601 5000 XXXX 0004 7500
  74. * A2-2 1003 0020 0100 2601 5000 XXXX 0005 7500
  75. * A2-3 1003 0020 0100 2601 5000 XXXX 0007 7500
  76. * NICAM 1003 0120 0100 2603 5000 XXXX 000B 7500
  77. *
  78. * L/L'
  79. * Mono 0003 0200 0100 7C03 5000 2200 0009 7500
  80. * NICAM 0003 0120 0100 7C03 5000 XXXX 0009 7500
  81. *
  82. * M
  83. * Mono 1003 0200 0100 2B03 5000 2B00 0002 7500
  84. *
  85. * For Asia, replace the 0x26XX in FM_PRESCALE with 0x14XX.
  86. *
  87. * Bilingual selection in A2/NICAM:
  88. *
  89. * High byte of SOURCE Left chan Right chan
  90. * 0x01 MAIN SUB
  91. * 0x03 MAIN MAIN
  92. * 0x04 SUB SUB
  93. *
  94. * Force mono in NICAM by setting the high byte of SOURCE to 0x02 (L/L') or
  95. * 0x00 (all other bands). Force mono in A2 with FMONO_A2:
  96. *
  97. * FMONO_A2
  98. * 10/0022
  99. * --------
  100. * Forced mono ON 07F0
  101. * Forced mono OFF 0190
  102. */
  103. static const struct {
  104. enum { AUD_MONO, AUD_A2, AUD_NICAM, AUD_NICAM_L } audio_mode;
  105. u16 modus;
  106. u16 source;
  107. u16 acb;
  108. u16 fm_prescale;
  109. u16 nicam_prescale;
  110. u16 scart_prescale;
  111. u16 system;
  112. u16 volume;
  113. } mpx_audio_modes[] = {
  114. /* Auto */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
  115. 0x5000, 0x0000, 0x0001, 0x7500 },
  116. /* B/G Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
  117. 0x5000, 0x0000, 0x0003, 0x7500 },
  118. /* B/G A2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
  119. 0x5000, 0x0000, 0x0003, 0x7500 },
  120. /* B/G NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
  121. 0x5000, 0x0000, 0x0008, 0x7500 },
  122. /* I Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
  123. 0x7900, 0x0000, 0x000A, 0x7500 },
  124. /* I NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
  125. 0x7900, 0x0000, 0x000A, 0x7500 },
  126. /* D/K Mono */ { AUD_MONO, 0x1003, 0x0020, 0x0100, 0x2603,
  127. 0x5000, 0x0000, 0x0004, 0x7500 },
  128. /* D/K A2-1 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
  129. 0x5000, 0x0000, 0x0004, 0x7500 },
  130. /* D/K A2-2 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
  131. 0x5000, 0x0000, 0x0005, 0x7500 },
  132. /* D/K A2-3 */ { AUD_A2, 0x1003, 0x0020, 0x0100, 0x2601,
  133. 0x5000, 0x0000, 0x0007, 0x7500 },
  134. /* D/K NICAM */ { AUD_NICAM, 0x1003, 0x0120, 0x0100, 0x2603,
  135. 0x5000, 0x0000, 0x000B, 0x7500 },
  136. /* L/L' Mono */ { AUD_MONO, 0x0003, 0x0200, 0x0100, 0x7C03,
  137. 0x5000, 0x2200, 0x0009, 0x7500 },
  138. /* L/L' NICAM */{ AUD_NICAM_L, 0x0003, 0x0120, 0x0100, 0x7C03,
  139. 0x5000, 0x0000, 0x0009, 0x7500 },
  140. };
  141. #define MPX_NUM_MODES ARRAY_SIZE(mpx_audio_modes)
  142. static int mpx_setup(struct sony_btf_mpx *t)
  143. {
  144. struct i2c_client *client = v4l2_get_subdevdata(&t->sd);
  145. u16 source = 0;
  146. u8 buffer[3];
  147. struct i2c_msg msg;
  148. int mode = t->mpxmode;
  149. /* reset MPX */
  150. buffer[0] = 0x00;
  151. buffer[1] = 0x80;
  152. buffer[2] = 0x00;
  153. msg.addr = client->addr;
  154. msg.flags = 0;
  155. msg.len = 3;
  156. msg.buf = buffer;
  157. i2c_transfer(client->adapter, &msg, 1);
  158. buffer[1] = 0x00;
  159. i2c_transfer(client->adapter, &msg, 1);
  160. if (t->audmode != V4L2_TUNER_MODE_MONO)
  161. mode++;
  162. if (mpx_audio_modes[mode].audio_mode != AUD_MONO) {
  163. switch (t->audmode) {
  164. case V4L2_TUNER_MODE_MONO:
  165. switch (mpx_audio_modes[mode].audio_mode) {
  166. case AUD_A2:
  167. source = mpx_audio_modes[mode].source;
  168. break;
  169. case AUD_NICAM:
  170. source = 0x0000;
  171. break;
  172. case AUD_NICAM_L:
  173. source = 0x0200;
  174. break;
  175. default:
  176. break;
  177. }
  178. break;
  179. case V4L2_TUNER_MODE_STEREO:
  180. source = mpx_audio_modes[mode].source;
  181. break;
  182. case V4L2_TUNER_MODE_LANG1:
  183. source = 0x0300;
  184. break;
  185. case V4L2_TUNER_MODE_LANG2:
  186. source = 0x0400;
  187. break;
  188. }
  189. source |= mpx_audio_modes[mode].source & 0x00ff;
  190. } else
  191. source = mpx_audio_modes[mode].source;
  192. mpx_write(client, 0x10, 0x0030, mpx_audio_modes[mode].modus);
  193. mpx_write(client, 0x12, 0x0008, source);
  194. mpx_write(client, 0x12, 0x0013, mpx_audio_modes[mode].acb);
  195. mpx_write(client, 0x12, 0x000e,
  196. mpx_audio_modes[mode].fm_prescale);
  197. mpx_write(client, 0x12, 0x0010,
  198. mpx_audio_modes[mode].nicam_prescale);
  199. mpx_write(client, 0x12, 0x000d,
  200. mpx_audio_modes[mode].scart_prescale);
  201. mpx_write(client, 0x10, 0x0020, mpx_audio_modes[mode].system);
  202. mpx_write(client, 0x12, 0x0000, mpx_audio_modes[mode].volume);
  203. if (mpx_audio_modes[mode].audio_mode == AUD_A2)
  204. mpx_write(client, 0x10, 0x0022,
  205. t->audmode == V4L2_TUNER_MODE_MONO ? 0x07f0 : 0x0190);
  206. #ifdef MPX_DEBUG
  207. {
  208. u8 buf1[3], buf2[2];
  209. struct i2c_msg msgs[2];
  210. v4l2_info(client,
  211. "MPX registers: %04x %04x %04x %04x %04x %04x %04x %04x\n",
  212. mpx_audio_modes[mode].modus,
  213. source,
  214. mpx_audio_modes[mode].acb,
  215. mpx_audio_modes[mode].fm_prescale,
  216. mpx_audio_modes[mode].nicam_prescale,
  217. mpx_audio_modes[mode].scart_prescale,
  218. mpx_audio_modes[mode].system,
  219. mpx_audio_modes[mode].volume);
  220. buf1[0] = 0x11;
  221. buf1[1] = 0x00;
  222. buf1[2] = 0x7e;
  223. msgs[0].addr = client->addr;
  224. msgs[0].flags = 0;
  225. msgs[0].len = 3;
  226. msgs[0].buf = buf1;
  227. msgs[1].addr = client->addr;
  228. msgs[1].flags = I2C_M_RD;
  229. msgs[1].len = 2;
  230. msgs[1].buf = buf2;
  231. i2c_transfer(client->adapter, msgs, 2);
  232. v4l2_info(client, "MPX system: %02x%02x\n",
  233. buf2[0], buf2[1]);
  234. buf1[0] = 0x11;
  235. buf1[1] = 0x02;
  236. buf1[2] = 0x00;
  237. i2c_transfer(client->adapter, msgs, 2);
  238. v4l2_info(client, "MPX status: %02x%02x\n",
  239. buf2[0], buf2[1]);
  240. }
  241. #endif
  242. return 0;
  243. }
  244. static int sony_btf_mpx_s_std(struct v4l2_subdev *sd, v4l2_std_id std)
  245. {
  246. struct sony_btf_mpx *t = to_state(sd);
  247. int default_mpx_mode = 0;
  248. if (std & V4L2_STD_PAL_BG)
  249. default_mpx_mode = 1;
  250. else if (std & V4L2_STD_PAL_I)
  251. default_mpx_mode = 4;
  252. else if (std & V4L2_STD_PAL_DK)
  253. default_mpx_mode = 6;
  254. else if (std & V4L2_STD_SECAM_L)
  255. default_mpx_mode = 11;
  256. if (default_mpx_mode != t->mpxmode) {
  257. t->mpxmode = default_mpx_mode;
  258. mpx_setup(t);
  259. }
  260. return 0;
  261. }
  262. static int sony_btf_mpx_g_tuner(struct v4l2_subdev *sd, struct v4l2_tuner *vt)
  263. {
  264. struct sony_btf_mpx *t = to_state(sd);
  265. vt->capability = V4L2_TUNER_CAP_NORM |
  266. V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_LANG1 |
  267. V4L2_TUNER_CAP_LANG2;
  268. vt->rxsubchans = V4L2_TUNER_SUB_MONO |
  269. V4L2_TUNER_SUB_STEREO | V4L2_TUNER_SUB_LANG1 |
  270. V4L2_TUNER_SUB_LANG2;
  271. vt->audmode = t->audmode;
  272. return 0;
  273. }
  274. static int sony_btf_mpx_s_tuner(struct v4l2_subdev *sd, const struct v4l2_tuner *vt)
  275. {
  276. struct sony_btf_mpx *t = to_state(sd);
  277. if (vt->type != V4L2_TUNER_ANALOG_TV)
  278. return -EINVAL;
  279. if (vt->audmode != t->audmode) {
  280. t->audmode = vt->audmode;
  281. mpx_setup(t);
  282. }
  283. return 0;
  284. }
  285. /* --------------------------------------------------------------------------*/
  286. static const struct v4l2_subdev_tuner_ops sony_btf_mpx_tuner_ops = {
  287. .s_tuner = sony_btf_mpx_s_tuner,
  288. .g_tuner = sony_btf_mpx_g_tuner,
  289. };
  290. static const struct v4l2_subdev_video_ops sony_btf_mpx_video_ops = {
  291. .s_std = sony_btf_mpx_s_std,
  292. };
  293. static const struct v4l2_subdev_ops sony_btf_mpx_ops = {
  294. .tuner = &sony_btf_mpx_tuner_ops,
  295. .video = &sony_btf_mpx_video_ops,
  296. };
  297. /* --------------------------------------------------------------------------*/
  298. static int sony_btf_mpx_probe(struct i2c_client *client,
  299. const struct i2c_device_id *id)
  300. {
  301. struct sony_btf_mpx *t;
  302. struct v4l2_subdev *sd;
  303. if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_I2C_BLOCK))
  304. return -ENODEV;
  305. v4l_info(client, "chip found @ 0x%x (%s)\n",
  306. client->addr << 1, client->adapter->name);
  307. t = devm_kzalloc(&client->dev, sizeof(*t), GFP_KERNEL);
  308. if (t == NULL)
  309. return -ENOMEM;
  310. sd = &t->sd;
  311. v4l2_i2c_subdev_init(sd, client, &sony_btf_mpx_ops);
  312. /* Initialize sony_btf_mpx */
  313. t->mpxmode = 0;
  314. t->audmode = V4L2_TUNER_MODE_STEREO;
  315. return 0;
  316. }
  317. static void sony_btf_mpx_remove(struct i2c_client *client)
  318. {
  319. struct v4l2_subdev *sd = i2c_get_clientdata(client);
  320. v4l2_device_unregister_subdev(sd);
  321. }
  322. /* ----------------------------------------------------------------------- */
  323. static const struct i2c_device_id sony_btf_mpx_id[] = {
  324. { "sony-btf-mpx", 0 },
  325. { }
  326. };
  327. MODULE_DEVICE_TABLE(i2c, sony_btf_mpx_id);
  328. static struct i2c_driver sony_btf_mpx_driver = {
  329. .driver = {
  330. .name = "sony-btf-mpx",
  331. },
  332. .probe = sony_btf_mpx_probe,
  333. .remove = sony_btf_mpx_remove,
  334. .id_table = sony_btf_mpx_id,
  335. };
  336. module_i2c_driver(sony_btf_mpx_driver);