sony-btf-mpx.c 11 KB

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