msp3400.c
上传用户:jlfgdled
上传日期:2013-04-10
资源大小:33168k
文件大小:42k
源码类别:

Linux/Unix编程

开发平台:

Unix_Linux

  1. /*
  2.  * programming the msp34* sound processor family
  3.  *
  4.  * (c) 1997-2001 Gerd Knorr <kraxel@bytesex.org>
  5.  *
  6.  * what works and what doesn't:
  7.  *
  8.  *  AM-Mono
  9.  *      Support for Hauppauge cards added (decoding handled by tuner) added by
  10.  *      Frederic Crozat <fcrozat@mail.dotcom.fr>
  11.  *
  12.  *  FM-Mono
  13.  *      should work. The stereo modes are backward compatible to FM-mono,
  14.  *      therefore FM-Mono should be allways available.
  15.  *
  16.  *  FM-Stereo (B/G, used in germany)
  17.  *      should work, with autodetect
  18.  *
  19.  *  FM-Stereo (satellite)
  20.  *      should work, no autodetect (i.e. default is mono, but you can
  21.  *      switch to stereo -- untested)
  22.  *
  23.  *  NICAM (B/G, L , used in UK, Scandinavia, Spain and France)
  24.  *      should work, with autodetect. Support for NICAM was added by
  25.  *      Pekka Pietikainen <pp@netppl.fi>
  26.  *
  27.  *
  28.  * TODO:
  29.  *   - better SAT support
  30.  *
  31.  *
  32.  * 980623  Thomas Sailer (sailer@ife.ee.ethz.ch)
  33.  *         using soundcore instead of OSS
  34.  *
  35.  */
  36. #include <linux/config.h>
  37. #include <linux/module.h>
  38. #include <linux/kernel.h>
  39. #include <linux/sched.h>
  40. #include <linux/string.h>
  41. #include <linux/timer.h>
  42. #include <linux/delay.h>
  43. #include <linux/errno.h>
  44. #include <linux/slab.h>
  45. #include <linux/i2c.h>
  46. #include <linux/videodev.h>
  47. #include <asm/semaphore.h>
  48. #include <linux/init.h>
  49. #ifdef CONFIG_SMP
  50. #include <asm/pgtable.h>
  51. #include <linux/smp_lock.h>
  52. #endif
  53. /* kernel_thread */
  54. #define __KERNEL_SYSCALLS__
  55. #include <linux/unistd.h>
  56. #include "audiochip.h"
  57. #include "msp3400.h"
  58. /* Addresses to scan */
  59. static unsigned short normal_i2c[] = {I2C_CLIENT_END};
  60. static unsigned short normal_i2c_range[] = {0x40,0x40,I2C_CLIENT_END};
  61. static unsigned short probe[2]        = { I2C_CLIENT_END, I2C_CLIENT_END };
  62. static unsigned short probe_range[2]  = { I2C_CLIENT_END, I2C_CLIENT_END };
  63. static unsigned short ignore[2]       = { I2C_CLIENT_END, I2C_CLIENT_END };
  64. static unsigned short ignore_range[2] = { I2C_CLIENT_END, I2C_CLIENT_END };
  65. static unsigned short force[2]        = { I2C_CLIENT_END, I2C_CLIENT_END };
  66. static struct i2c_client_address_data addr_data = {
  67. normal_i2c, normal_i2c_range, 
  68. probe, probe_range, 
  69. ignore, ignore_range, 
  70. force
  71. };
  72. /* insmod parameters */
  73. static int debug   = 0;    /* debug output */
  74. static int once    = 0;    /* no continous stereo monitoring */
  75. static int amsound = 0;    /* hard-wire AM sound at 6.5 Hz (france),
  76.       the autoscan seems work well only with FM... */
  77. static int simple  = -1;   /* use short programming (>= msp3410 only) */
  78. static int dolby   = 0;
  79. #define DFP_COUNT 0x41
  80. static const int bl_dfp[] = {
  81. 0x00, 0x01, 0x02, 0x03,  0x06, 0x08, 0x09, 0x0a,
  82. 0x0b, 0x0d, 0x0e, 0x10
  83. };
  84. struct msp3400c {
  85. int simple;
  86. int nicam;
  87. int mode;
  88. int norm;
  89. int stereo;
  90. int nicam_on;
  91. int acb;
  92. int main, second; /* sound carrier */
  93. int input;
  94. int muted;
  95. int left, right; /* volume */
  96. int bass, treble;
  97. /* shadow register set */
  98. int dfp_regs[DFP_COUNT];
  99. /* thread */
  100. struct task_struct  *thread;
  101. wait_queue_head_t    wq;
  102. struct semaphore    *notify;
  103. int                  active,restart,rmmod;
  104. int                  watch_stereo;
  105. struct timer_list    wake_stereo;
  106. };
  107. #define MSP3400_MAX 4
  108. static struct i2c_client *msps[MSP3400_MAX];
  109. #define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
  110. /* ---------------------------------------------------------------------- */
  111. #define dprintk     if (debug) printk
  112. MODULE_PARM(once,"i");
  113. MODULE_PARM(debug,"i");
  114. MODULE_PARM(simple,"i");
  115. MODULE_PARM(amsound,"i");
  116. MODULE_PARM(dolby,"i");
  117. MODULE_DESCRIPTION("device driver for msp34xx TV sound processor");
  118. MODULE_AUTHOR("Gerd Knorr");
  119. MODULE_LICENSE("GPL");
  120. /* ---------------------------------------------------------------------- */
  121. #define I2C_MSP3400C       0x80
  122. #define I2C_MSP3400C_DEM   0x10
  123. #define I2C_MSP3400C_DFP   0x12
  124. /* ----------------------------------------------------------------------- */
  125. /* functions for talking to the MSP3400C Sound processor                   */
  126. static int msp3400c_reset(struct i2c_client *client)
  127. {
  128.         static char reset_off[3] = { 0x00, 0x80, 0x00 };
  129.         static char reset_on[3]  = { 0x00, 0x00, 0x00 };
  130.         i2c_master_send(client,reset_off,3);  /* XXX ignore errors here */
  131.         if (3 != i2c_master_send(client,reset_on, 3)) {
  132. printk(KERN_ERR "msp3400: chip reset failed, penguin on i2c bus?n");
  133.                 return -1;
  134. }
  135.         return 0;
  136. }
  137. static int
  138. msp3400c_read(struct i2c_client *client, int dev, int addr)
  139. {
  140. int err;
  141.         unsigned char write[3];
  142.         unsigned char read[2];
  143.         struct i2c_msg msgs[2] = {
  144.                 { client->addr, 0,        3, write },
  145.                 { client->addr, I2C_M_RD, 2, read  }
  146.         };
  147.         write[0] = dev+1;
  148.         write[1] = addr >> 8;
  149.         write[2] = addr & 0xff;
  150. for (err = 0; err < 3;) {
  151. if (2 == i2c_transfer(client->adapter,msgs,2))
  152. break;
  153. err++;
  154. printk(KERN_WARNING "msp34xx: I/O error #%d (read 0x%02x/0x%02x)n",
  155.        err, dev, addr);
  156. current->state = TASK_INTERRUPTIBLE;
  157. schedule_timeout(HZ/10);
  158. }
  159. if (3 == err) {
  160. printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|n");
  161. msp3400c_reset(client);
  162. return -1;
  163. }
  164.         return read[0] << 8 | read[1];
  165. }
  166. static int
  167. msp3400c_write(struct i2c_client *client, int dev, int addr, int val)
  168. {
  169. int err;
  170.         unsigned char buffer[5];
  171.         buffer[0] = dev;
  172.         buffer[1] = addr >> 8;
  173.         buffer[2] = addr &  0xff;
  174.         buffer[3] = val  >> 8;
  175.         buffer[4] = val  &  0xff;
  176. for (err = 0; err < 3;) {
  177. if (5 == i2c_master_send(client, buffer, 5))
  178. break;
  179. err++;
  180. printk(KERN_WARNING "msp34xx: I/O error #%d (write 0x%02x/0x%02x)n",
  181.        err, dev, addr);
  182. current->state = TASK_INTERRUPTIBLE;
  183. schedule_timeout(HZ/10);
  184. }
  185. if (3 == err) {
  186. printk(KERN_WARNING "msp34xx: giving up, reseting chip. Sound will go off, sorry folks :-|n");
  187. msp3400c_reset(client);
  188. return -1;
  189. }
  190. return 0;
  191. }
  192. /* ------------------------------------------------------------------------ */
  193. /* This macro is allowed for *constants* only, gcc must calculate it
  194.    at compile time.  Remember -- no floats in kernel mode */
  195. #define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
  196. #define MSP_MODE_AM_DETECT   0
  197. #define MSP_MODE_FM_RADIO    2
  198. #define MSP_MODE_FM_TERRA    3
  199. #define MSP_MODE_FM_SAT      4
  200. #define MSP_MODE_FM_NICAM1   5
  201. #define MSP_MODE_FM_NICAM2   6
  202. #define MSP_MODE_AM_NICAM    7
  203. #define MSP_MODE_BTSC        8
  204. #define MSP_MODE_EXTERN      9
  205. static struct MSP_INIT_DATA_DEM {
  206. int fir1[6];
  207. int fir2[6];
  208. int cdo1;
  209. int cdo2;
  210. int ad_cv;
  211. int mode_reg;
  212. int dfp_src;
  213. int dfp_matrix;
  214. } msp_init_data[] = {
  215. /* AM (for carrier detect / msp3400) */
  216. { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
  217.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  218.   0x00d0, 0x0500,   0x0020, 0x3000},
  219. /* AM (for carrier detect / msp3410) */
  220. { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
  221.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  222.   0x00d0, 0x0100,   0x0020, 0x3000},
  223. /* FM Radio */
  224. { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
  225.   MSP_CARRIER(10.7), MSP_CARRIER(10.7),
  226.   0x00d0, 0x0480, 0x0020, 0x3000 },
  227. /* Terrestial FM-mono + FM-stereo */
  228. { {  3, 18, 27, 48, 66, 72 }, {  3, 18, 27, 48, 66, 72 },
  229.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  230.   0x00d0, 0x0480,   0x0030, 0x3000},
  231. /* Sat FM-mono */
  232. { {  1,  9, 14, 24, 33, 37 }, {  3, 18, 27, 48, 66, 72 },
  233.   MSP_CARRIER(6.5), MSP_CARRIER(6.5),
  234.   0x00c6, 0x0480,   0x0000, 0x3000},
  235. /* NICAM/FM --  B/G (5.5/5.85), D/K (6.5/5.85) */
  236. { { -2, -8, -10, 10, 50, 86 }, {  3, 18, 27, 48, 66, 72 },
  237.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  238.   0x00d0, 0x0040,   0x0120, 0x3000},
  239. /* NICAM/FM -- I (6.0/6.552) */
  240. { {  2, 4, -6, -4, 40, 94 }, {  3, 18, 27, 48, 66, 72 },
  241.   MSP_CARRIER(6.0), MSP_CARRIER(6.0),
  242.   0x00d0, 0x0040,   0x0120, 0x3000},
  243. /* NICAM/AM -- L (6.5/5.85) */
  244. { {  -2, -8, -10, 10, 50, 86 }, {  -4, -12, -9, 23, 79, 126 },
  245.   MSP_CARRIER(6.5), MSP_CARRIER(6.5),
  246.   0x00c6, 0x0140,   0x0120, 0x7c03},
  247. };
  248. struct CARRIER_DETECT {
  249. int   cdo;
  250. char *name;
  251. };
  252. static struct CARRIER_DETECT carrier_detect_main[] = {
  253. /* main carrier */
  254. { MSP_CARRIER(4.5),        "4.5   NTSC"                   }, 
  255. { MSP_CARRIER(5.5),        "5.5   PAL B/G"                }, 
  256. { MSP_CARRIER(6.0),        "6.0   PAL I"                  },
  257. { MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
  258. };
  259. static struct CARRIER_DETECT carrier_detect_55[] = {
  260. /* PAL B/G */
  261. { MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     }, 
  262. { MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
  263. };
  264. static struct CARRIER_DETECT carrier_detect_65[] = {
  265. /* PAL SAT / SECAM */
  266. { MSP_CARRIER(5.85),       "5.85  PAL D/K + SECAM NICAM" },
  267. { MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
  268. { MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
  269. { MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
  270. { MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
  271. { MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
  272. };
  273. #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
  274. /* ----------------------------------------------------------------------- */
  275. #define SCART_MASK    0
  276. #define SCART_IN1     1
  277. #define SCART_IN2     2
  278. #define SCART_IN1_DA  3
  279. #define SCART_IN2_DA  4
  280. #define SCART_IN3     5
  281. #define SCART_IN4     6
  282. #define SCART_MONO    7
  283. #define SCART_MUTE    8
  284. static int scarts[3][9] = {
  285.   /* MASK    IN1     IN2     IN1_DA  IN2_DA  IN3     IN4     MONO    MUTE   */
  286.   {  0x0320, 0x0000, 0x0200, -1,     -1,     0x0300, 0x0020, 0x0100, 0x0320 },
  287.   {  0x0c40, 0x0440, 0x0400, 0x0c00, 0x0040, 0x0000, 0x0840, 0x0800, 0x0c40 },
  288.   {  0x3080, 0x1000, 0x1080, 0x0000, 0x0080, 0x2080, 0x3080, 0x2000, 0x3000 },
  289. };
  290. static char *scart_names[] = {
  291.   "mask", "in1", "in2", "in1 da", "in2 da", "in3", "in4", "mono", "mute"
  292. };
  293. static void
  294. msp3400c_set_scart(struct i2c_client *client, int in, int out)
  295. {
  296. struct msp3400c *msp = client->data;
  297. if (-1 == scarts[out][in])
  298. return;
  299. dprintk("msp34xx: scart switch: %s => %dn",scart_names[in],out);
  300. msp->acb &= ~scarts[out][SCART_MASK];
  301. msp->acb |=  scarts[out][in];
  302. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0013, msp->acb);
  303. }
  304. /* ------------------------------------------------------------------------ */
  305. static void msp3400c_setcarrier(struct i2c_client *client, int cdo1, int cdo2)
  306. {
  307. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
  308. msp3400c_write(client,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
  309. msp3400c_write(client,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
  310. msp3400c_write(client,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
  311. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
  312. }
  313. static void msp3400c_setvolume(struct i2c_client *client,
  314.        int muted, int left, int right)
  315. {
  316. int vol = 0,val = 0,balance = 0;
  317. if (!muted) {
  318. vol     = (left > right) ? left : right;
  319. val     = (vol * 0x73 / 65535) << 8;
  320. }
  321. if (vol > 0) {
  322. balance = ((right-left) * 127) / vol;
  323. }
  324. dprintk("msp34xx: setvolume: mute=%s %d:%d  v=0x%02x b=0x%02xn",
  325. muted ? "on" : "off", left, right, val>>8, balance);
  326. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
  327. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0006, val); /* headphones  */
  328. /* scart - on/off only */
  329. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0);
  330. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0001, balance << 8);
  331. }
  332. static void msp3400c_setbass(struct i2c_client *client, int bass)
  333. {
  334. int val = ((bass-32768) * 0x60 / 65535) << 8;
  335. dprintk("msp34xx: setbass: %d 0x%02xn",bass, val>>8);
  336. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
  337. }
  338. static void msp3400c_settreble(struct i2c_client *client, int treble)
  339. {
  340. int val = ((treble-32768) * 0x60 / 65535) << 8;
  341. dprintk("msp34xx: settreble: %d 0x%02xn",treble, val>>8);
  342. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
  343. }
  344. static void msp3400c_setmode(struct i2c_client *client, int type)
  345. {
  346. struct msp3400c *msp = client->data;
  347. int i;
  348. dprintk("msp3400: setmode: %dn",type);
  349. msp->mode   = type;
  350. msp->stereo = VIDEO_SOUND_MONO;
  351. msp3400c_write(client,I2C_MSP3400C_DEM, 0x00bb,          /* ad_cv */
  352.        msp_init_data[type].ad_cv);
  353.     
  354. for (i = 5; i >= 0; i--)                                   /* fir 1 */
  355. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0001,
  356.        msp_init_data[type].fir1[i]);
  357.     
  358. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
  359. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0040);
  360. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005, 0x0000);
  361. for (i = 5; i >= 0; i--)
  362. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0005,
  363.        msp_init_data[type].fir2[i]);
  364.     
  365. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0083,     /* MODE_REG */
  366.        msp_init_data[type].mode_reg);
  367.     
  368. msp3400c_setcarrier(client, msp_init_data[type].cdo1,
  369.     msp_init_data[type].cdo2);
  370.     
  371. msp3400c_write(client,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
  372. if (dolby) {
  373. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
  374.        0x0520); /* I2S1 */
  375. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
  376.        0x0620); /* I2S2 */
  377. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
  378.        msp_init_data[type].dfp_src);
  379. } else {
  380. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,
  381.        msp_init_data[type].dfp_src);
  382. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,
  383.        msp_init_data[type].dfp_src);
  384. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,
  385.        msp_init_data[type].dfp_src);
  386. }
  387. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,
  388.        msp_init_data[type].dfp_src);
  389. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e,
  390.        msp_init_data[type].dfp_matrix);
  391. if (msp->nicam) {
  392. /* nicam prescale */
  393. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0010, 0x5a00); /* was: 0x3000 */
  394. }
  395. }
  396. /* turn on/off nicam + stereo */
  397. static void msp3400c_setstereo(struct i2c_client *client, int mode)
  398. {
  399. static char *strmode[] = { "0", "mono", "stereo", "3",
  400.    "lang1", "5", "6", "7", "lang2" };
  401. struct msp3400c *msp = client->data;
  402. int nicam=0; /* channel source: FM/AM or nicam */
  403. int src=0;
  404. /* switch demodulator */
  405. switch (msp->mode) {
  406. case MSP_MODE_FM_TERRA:
  407. dprintk("msp3400: FM setstereo: %sn",strmode[mode]);
  408. msp3400c_setcarrier(client,msp->second,msp->main);
  409. switch (mode) {
  410. case VIDEO_SOUND_STEREO:
  411. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3001);
  412. break;
  413. case VIDEO_SOUND_MONO:
  414. case VIDEO_SOUND_LANG1:
  415. case VIDEO_SOUND_LANG2:
  416. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000e, 0x3000);
  417. break;
  418. }
  419. break;
  420. case MSP_MODE_FM_SAT:
  421. dprintk("msp3400: SAT setstereo: %sn",strmode[mode]);
  422. switch (mode) {
  423. case VIDEO_SOUND_MONO:
  424. msp3400c_setcarrier(client, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
  425. break;
  426. case VIDEO_SOUND_STEREO:
  427. msp3400c_setcarrier(client, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
  428. break;
  429. case VIDEO_SOUND_LANG1:
  430. msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
  431. break;
  432. case VIDEO_SOUND_LANG2:
  433. msp3400c_setcarrier(client, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
  434. break;
  435. }
  436. break;
  437. case MSP_MODE_FM_NICAM1:
  438. case MSP_MODE_FM_NICAM2:
  439. case MSP_MODE_AM_NICAM:
  440. dprintk("msp3400: NICAM setstereo: %sn",strmode[mode]);
  441. msp3400c_setcarrier(client,msp->second,msp->main);
  442. if (msp->nicam_on)
  443. nicam=0x0100;
  444. break;
  445. case MSP_MODE_BTSC:
  446. dprintk("msp3400: BTSC setstereo: %sn",strmode[mode]);
  447. nicam=0x0300;
  448. break;
  449. case MSP_MODE_EXTERN:
  450. dprintk("msp3400: extern setstereo: %sn",strmode[mode]);
  451. nicam = 0x0200;
  452. break;
  453. case MSP_MODE_FM_RADIO:
  454. dprintk("msp3400: FM-Radio setstereo: %sn",strmode[mode]);
  455. break;
  456. default:
  457. dprintk("msp3400: mono setstereon");
  458. return;
  459. }
  460. /* switch audio */
  461. switch (mode) {
  462. case VIDEO_SOUND_STEREO:
  463. src = 0x0020 | nicam;
  464. #if 0 
  465. /* spatial effect */
  466. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0005,0x4000);
  467. #endif
  468. break;
  469. case VIDEO_SOUND_MONO:
  470. if (msp->mode == MSP_MODE_AM_NICAM) {
  471. dprintk("msp3400: switching to AM monon");
  472. /* AM mono decoding is handled by tuner, not MSP chip */
  473. /* SCART switching control register */
  474. msp3400c_set_scart(client,SCART_MONO,0);
  475. src = 0x0200;
  476. break;
  477. }
  478. case VIDEO_SOUND_LANG1:
  479. src = 0x0000 | nicam;
  480. break;
  481. case VIDEO_SOUND_LANG2:
  482. src = 0x0010 | nicam;
  483. break;
  484. }
  485. dprintk("msp3400: setstereo final source/matrix = 0x%xn", src);
  486. if (dolby) {
  487. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,0x0520);
  488. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,0x0620);
  489. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
  490. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
  491. } else {
  492. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0008,src);
  493. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0009,src);
  494. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000a,src);
  495. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000b,src);
  496. }
  497. }
  498. static void
  499. msp3400c_print_mode(struct msp3400c *msp)
  500. {
  501. if (msp->main == msp->second) {
  502. printk("msp3400: mono sound carrier: %d.%03d MHzn",
  503.        msp->main/910000,(msp->main/910)%1000);
  504. } else {
  505. printk("msp3400: main sound carrier: %d.%03d MHzn",
  506.        msp->main/910000,(msp->main/910)%1000);
  507. }
  508. if (msp->mode == MSP_MODE_FM_NICAM1 ||
  509.     msp->mode == MSP_MODE_FM_NICAM2)
  510. printk("msp3400: NICAM/FM carrier   : %d.%03d MHzn",
  511.        msp->second/910000,(msp->second/910)%1000);
  512. if (msp->mode == MSP_MODE_AM_NICAM)
  513. printk("msp3400: NICAM/AM carrier   : %d.%03d MHzn",
  514.        msp->second/910000,(msp->second/910)%1000);
  515. if (msp->mode == MSP_MODE_FM_TERRA &&
  516.     msp->main != msp->second) {
  517. printk("msp3400: FM-stereo carrier : %d.%03d MHzn",
  518.        msp->second/910000,(msp->second/910)%1000);
  519. }
  520. }
  521. static void
  522. msp3400c_restore_dfp(struct i2c_client *client)
  523. {
  524. struct msp3400c *msp = client->data;
  525. int i;
  526. for (i = 0; i < DFP_COUNT; i++) {
  527. if (-1 == msp->dfp_regs[i])
  528. continue;
  529. msp3400c_write(client,I2C_MSP3400C_DFP, i, msp->dfp_regs[i]);
  530. }
  531. }
  532. /* ----------------------------------------------------------------------- */
  533. struct REGISTER_DUMP {
  534. int   addr;
  535. char *name;
  536. };
  537. struct REGISTER_DUMP d1[] = {
  538. { 0x007e, "autodetect" },
  539. { 0x0023, "C_AD_BITS " },
  540. { 0x0038, "ADD_BITS  " },
  541. { 0x003e, "CIB_BITS  " },
  542. { 0x0057, "ERROR_RATE" },
  543. };
  544. static int
  545. autodetect_stereo(struct i2c_client *client)
  546. {
  547. struct msp3400c *msp = client->data;
  548. int val;
  549. int newstereo = msp->stereo;
  550. int newnicam  = msp->nicam_on;
  551. int update = 0;
  552. switch (msp->mode) {
  553. case MSP_MODE_FM_TERRA:
  554. val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x18);
  555. if (val > 32767)
  556. val -= 65536;
  557. dprintk("msp34xx: stereo detect register: %dn",val);
  558. if (val > 4096) {
  559. newstereo = VIDEO_SOUND_STEREO | VIDEO_SOUND_MONO;
  560. } else if (val < -4096) {
  561. newstereo = VIDEO_SOUND_LANG1 | VIDEO_SOUND_LANG2;
  562. } else {
  563. newstereo = VIDEO_SOUND_MONO;
  564. }
  565. newnicam = 0;
  566. break;
  567. case MSP_MODE_FM_NICAM1:
  568. case MSP_MODE_FM_NICAM2:
  569. case MSP_MODE_AM_NICAM:
  570. val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x23);
  571. dprintk("msp34xx: nicam sync=%d, mode=%dn",val & 1, (val & 0x1e) >> 1);
  572. if (val & 1) {
  573. /* nicam synced */
  574. switch ((val & 0x1e) >> 1)  {
  575. case 0:
  576. case 8:
  577. newstereo = VIDEO_SOUND_STEREO;
  578. break;
  579. case 1:
  580. case 9:
  581. newstereo = VIDEO_SOUND_MONO
  582. | VIDEO_SOUND_LANG1;
  583. break;
  584. case 2:
  585. case 10:
  586. newstereo = VIDEO_SOUND_MONO
  587. | VIDEO_SOUND_LANG1
  588. | VIDEO_SOUND_LANG2;
  589. break;
  590. default:
  591. newstereo = VIDEO_SOUND_MONO;
  592. break;
  593. }
  594. newnicam=1;
  595. } else {
  596. newnicam = 0;
  597. newstereo = VIDEO_SOUND_MONO;
  598. }
  599. break;
  600. case MSP_MODE_BTSC:
  601. val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x200);
  602. dprintk("msp3410: status=0x%x (pri=%s, sec=%s, %s%s%s)n",
  603. val,
  604. (val & 0x0002) ? "no"     : "yes",
  605. (val & 0x0004) ? "no"     : "yes",
  606. (val & 0x0040) ? "stereo" : "mono",
  607. (val & 0x0080) ? ", nicam 2nd mono" : "",
  608. (val & 0x0100) ? ", bilingual/SAP"  : "");
  609. newstereo = VIDEO_SOUND_MONO;
  610. if (val & 0x0040) newstereo |= VIDEO_SOUND_STEREO;
  611. if (val & 0x0100) newstereo |= VIDEO_SOUND_LANG1;
  612. break;
  613. }
  614. if (newstereo != msp->stereo) {
  615. update = 1;
  616. dprintk("msp34xx: watch: stereo %d => %dn",
  617. msp->stereo,newstereo);
  618. msp->stereo   = newstereo;
  619. }
  620. if (newnicam != msp->nicam_on) {
  621. update = 1;
  622. dprintk("msp34xx: watch: nicam %d => %dn",
  623. msp->nicam_on,newnicam);
  624. msp->nicam_on = newnicam;
  625. }
  626. return update;
  627. }
  628. /*
  629.  * A kernel thread for msp3400 control -- we don't want to block the
  630.  * in the ioctl while doing the sound carrier & stereo detect
  631.  */
  632. static void msp3400c_stereo_wake(unsigned long data)
  633. {
  634. struct msp3400c *msp = (struct msp3400c*)data;   /* XXX alpha ??? */
  635. wake_up_interruptible(&msp->wq);
  636. }
  637. /* stereo/multilang monitoring */
  638. static void watch_stereo(struct i2c_client *client)
  639. {
  640. struct msp3400c *msp = client->data;
  641. if (autodetect_stereo(client)) {
  642. if (msp->stereo & VIDEO_SOUND_STEREO)
  643. msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
  644. else if (msp->stereo & VIDEO_SOUND_LANG1)
  645. msp3400c_setstereo(client,VIDEO_SOUND_LANG1);
  646. else
  647. msp3400c_setstereo(client,VIDEO_SOUND_MONO);
  648. }
  649. if (once)
  650. msp->watch_stereo = 0;
  651. if (msp->watch_stereo)
  652. mod_timer(&msp->wake_stereo, jiffies+5*HZ);
  653. }
  654. static int msp3400c_thread(void *data)
  655. {
  656. struct i2c_client *client = data;
  657. struct msp3400c *msp = client->data;
  658. struct CARRIER_DETECT *cd;
  659. int count, max1,max2,val1,val2, val,this;
  660. #ifdef CONFIG_SMP
  661. lock_kernel();
  662. #endif
  663. daemonize();
  664. sigfillset(&current->blocked);
  665. strcpy(current->comm,"msp3400");
  666. msp->thread = current;
  667. #ifdef CONFIG_SMP
  668. unlock_kernel();
  669. #endif
  670. printk("msp3400: daemon startedn");
  671. if(msp->notify != NULL)
  672. up(msp->notify);
  673. for (;;) {
  674. if (msp->rmmod)
  675. goto done;
  676. if (debug > 1)
  677. printk("msp3400: thread: sleepn");
  678. interruptible_sleep_on(&msp->wq);
  679. if (debug > 1)
  680. printk("msp3400: thread: wakeupn");
  681. if (msp->rmmod || signal_pending(current))
  682. goto done;
  683. if (VIDEO_MODE_RADIO == msp->norm ||
  684.     MSP_MODE_EXTERN  == msp->mode)
  685. continue;  /* nothing to do */
  686. msp->active = 1;
  687. if (msp->watch_stereo) {
  688. watch_stereo(client);
  689. msp->active = 0;
  690. continue;
  691. }
  692. /* some time for the tuner to sync */
  693. current->state   = TASK_INTERRUPTIBLE;
  694. schedule_timeout(HZ/5);
  695. if (signal_pending(current))
  696. goto done;
  697. restart:
  698. if (VIDEO_MODE_RADIO == msp->norm ||
  699.     MSP_MODE_EXTERN  == msp->mode)
  700. continue;  /* nothing to do */
  701. msp->restart = 0;
  702. msp3400c_setvolume(client, msp->muted, 0, 0);
  703. msp3400c_setmode(client, MSP_MODE_AM_DETECT /* +1 */ );
  704. val1 = val2 = 0;
  705. max1 = max2 = -1;
  706. del_timer(&msp->wake_stereo);
  707. msp->watch_stereo = 0;
  708. /* carrier detect pass #1 -- main carrier */
  709. cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
  710. if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
  711. /* autodetect doesn't work well with AM ... */
  712. max1 = 3;
  713. count = 0;
  714. dprintk("msp3400: AM sound overriden");
  715. }
  716. for (this = 0; this < count; this++) {
  717. msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
  718. current->state   = TASK_INTERRUPTIBLE;
  719. schedule_timeout(HZ/10);
  720. if (signal_pending(current))
  721. goto done;
  722. if (msp->restart)
  723. msp->restart = 0;
  724. val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
  725. if (val > 32767)
  726. val -= 65536;
  727. if (val1 < val)
  728. val1 = val, max1 = this;
  729. dprintk("msp3400: carrier1 val: %5d / %sn", val,cd[this].name);
  730. }
  731. /* carrier detect pass #2 -- second (stereo) carrier */
  732. switch (max1) {
  733. case 1: /* 5.5 */
  734. cd = carrier_detect_55; count = CARRIER_COUNT(carrier_detect_55);
  735. break;
  736. case 3: /* 6.5 */
  737. cd = carrier_detect_65; count = CARRIER_COUNT(carrier_detect_65);
  738. break;
  739. case 0: /* 4.5 */
  740. case 2: /* 6.0 */
  741. default:
  742. cd = NULL; count = 0;
  743. break;
  744. }
  745. if (amsound && (msp->norm == VIDEO_MODE_SECAM)) {
  746. /* autodetect doesn't work well with AM ... */
  747. cd = NULL; count = 0; max2 = 0;
  748. }
  749. for (this = 0; this < count; this++) {
  750. msp3400c_setcarrier(client, cd[this].cdo,cd[this].cdo);
  751. current->state   = TASK_INTERRUPTIBLE;
  752. schedule_timeout(HZ/10);
  753. if (signal_pending(current))
  754. goto done;
  755. if (msp->restart)
  756. goto restart;
  757. val = msp3400c_read(client, I2C_MSP3400C_DFP, 0x1b);
  758. if (val > 32767)
  759. val -= 65536;
  760. if (val2 < val)
  761. val2 = val, max2 = this;
  762. dprintk("msp3400: carrier2 val: %5d / %sn", val,cd[this].name);
  763. }
  764. /* programm the msp3400 according to the results */
  765. msp->main   = carrier_detect_main[max1].cdo;
  766. switch (max1) {
  767. case 1: /* 5.5 */
  768. if (max2 == 0) {
  769. /* B/G FM-stereo */
  770. msp->second = carrier_detect_55[max2].cdo;
  771. msp3400c_setmode(client, MSP_MODE_FM_TERRA);
  772. msp->nicam_on = 0;
  773. msp3400c_setstereo(client, VIDEO_SOUND_MONO);
  774. msp->watch_stereo = 1;
  775. } else if (max2 == 1 && msp->nicam) {
  776. /* B/G NICAM */
  777. msp->second = carrier_detect_55[max2].cdo;
  778. msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
  779. msp->nicam_on = 1;
  780. msp3400c_setcarrier(client, msp->second, msp->main);
  781. msp->watch_stereo = 1;
  782. } else {
  783. goto no_second;
  784. }
  785. break;
  786. case 2: /* 6.0 */
  787. /* PAL I NICAM */
  788. msp->second = MSP_CARRIER(6.552);
  789. msp3400c_setmode(client, MSP_MODE_FM_NICAM2);
  790. msp->nicam_on = 1;
  791. msp3400c_setcarrier(client, msp->second, msp->main);
  792. msp->watch_stereo = 1;
  793. break;
  794. case 3: /* 6.5 */
  795. if (max2 == 1 || max2 == 2) {
  796. /* D/K FM-stereo */
  797. msp->second = carrier_detect_65[max2].cdo;
  798. msp3400c_setmode(client, MSP_MODE_FM_TERRA);
  799. msp->nicam_on = 0;
  800. msp3400c_setstereo(client, VIDEO_SOUND_MONO);
  801. msp->watch_stereo = 1;
  802. } else if (max2 == 0 &&
  803.    msp->norm == VIDEO_MODE_SECAM) {
  804. /* L NICAM or AM-mono */
  805. msp->second = carrier_detect_65[max2].cdo;
  806. msp3400c_setmode(client, MSP_MODE_AM_NICAM);
  807. msp->nicam_on = 0;
  808. msp3400c_setstereo(client, VIDEO_SOUND_MONO);
  809. msp3400c_setcarrier(client, msp->second, msp->main);
  810. /* volume prescale for SCART (AM mono input) */
  811. msp3400c_write(client,I2C_MSP3400C_DFP, 0x000d, 0x1900);
  812. msp->watch_stereo = 1;
  813. } else if (max2 == 0 && msp->nicam) {
  814. /* D/K NICAM */
  815. msp->second = carrier_detect_65[max2].cdo;
  816. msp3400c_setmode(client, MSP_MODE_FM_NICAM1);
  817. msp->nicam_on = 1;
  818. msp3400c_setcarrier(client, msp->second, msp->main);
  819. msp->watch_stereo = 1;
  820. } else {
  821. goto no_second;
  822. }
  823. break;
  824. case 0: /* 4.5 */
  825. default:
  826. no_second:
  827. msp->second = carrier_detect_main[max1].cdo;
  828. msp3400c_setmode(client, MSP_MODE_FM_TERRA);
  829. msp->nicam_on = 0;
  830. msp3400c_setcarrier(client, msp->second, msp->main);
  831. msp->stereo = VIDEO_SOUND_MONO;
  832. msp3400c_setstereo(client, VIDEO_SOUND_MONO);
  833. break;
  834. }
  835. /* unmute + restore dfp registers */
  836. msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
  837. msp3400c_restore_dfp(client);
  838. if (msp->watch_stereo)
  839. mod_timer(&msp->wake_stereo, jiffies+5*HZ);
  840. if (debug)
  841. msp3400c_print_mode(msp);
  842. msp->active = 0;
  843. }
  844. done:
  845. dprintk("msp3400: thread: exitn");
  846. msp->active = 0;
  847. msp->thread = NULL;
  848. if(msp->notify != NULL)
  849. up(msp->notify);
  850. return 0;
  851. }
  852. /* ----------------------------------------------------------------------- */
  853. /* this one uses the automatic sound standard detection of newer           */
  854. /* msp34xx chip versions                                                   */
  855. static struct MODES {
  856. int retval;
  857. int main, second;
  858. char *name;
  859. } modelist[] = {
  860. { 0x0000, 0, 0, "ERROR" },
  861. { 0x0001, 0, 0, "autodetect start" },
  862. { 0x0002, MSP_CARRIER(4.5), MSP_CARRIER(4.72), "4.5/4.72  M Dual FM-Stereo" },
  863. { 0x0003, MSP_CARRIER(5.5), MSP_CARRIER(5.7421875), "5.5/5.74  B/G Dual FM-Stereo" },
  864. { 0x0004, MSP_CARRIER(6.5), MSP_CARRIER(6.2578125), "6.5/6.25  D/K1 Dual FM-Stereo" },
  865. { 0x0005, MSP_CARRIER(6.5), MSP_CARRIER(6.7421875), "6.5/6.74  D/K2 Dual FM-Stereo" },
  866. { 0x0006, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  D/K FM-Mono (HDEV3)" },
  867. { 0x0008, MSP_CARRIER(5.5), MSP_CARRIER(5.85), "5.5/5.85  B/G NICAM FM" },
  868. { 0x0009, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  L NICAM AM" },
  869. { 0x000a, MSP_CARRIER(6.0), MSP_CARRIER(6.55), "6.0/6.55  I NICAM FM" },
  870. { 0x000b, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM" },
  871. { 0x000c, MSP_CARRIER(6.5), MSP_CARRIER(5.85), "6.5/5.85  D/K NICAM FM (HDEV2)" },
  872. { 0x0020, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Stereo" },
  873. { 0x0021, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M BTSC-Mono + SAP" },
  874. { 0x0030, MSP_CARRIER(4.5), MSP_CARRIER(4.5), "4.5  M EIA-J Japan Stereo" },
  875. { 0x0040, MSP_CARRIER(10.7), MSP_CARRIER(10.7), "10.7  FM-Stereo Radio" },
  876. { 0x0050, MSP_CARRIER(6.5), MSP_CARRIER(6.5), "6.5  SAT-Mono" },
  877. { 0x0051, MSP_CARRIER(7.02), MSP_CARRIER(7.20), "7.02/7.20  SAT-Stereo" },
  878. { 0x0060, MSP_CARRIER(7.2), MSP_CARRIER(7.2), "7.2  SAT ADR" },
  879. {     -1, 0, 0, NULL }, /* EOF */
  880. };
  881.  
  882. static int msp3410d_thread(void *data)
  883. {
  884. struct i2c_client *client = data;
  885. struct msp3400c *msp = client->data;
  886. int mode,val,i,std;
  887.     
  888. #ifdef CONFIG_SMP
  889. lock_kernel();
  890. #endif
  891.     
  892. daemonize();
  893. sigfillset(&current->blocked);
  894. strcpy(current->comm,"msp3410 [auto]");
  895. msp->thread = current;
  896. #ifdef CONFIG_SMP
  897. unlock_kernel();
  898. #endif
  899. printk("msp3410: daemon startedn");
  900. if(msp->notify != NULL)
  901. up(msp->notify);
  902. for (;;) {
  903. if (msp->rmmod)
  904. goto done;
  905. if (debug > 1)
  906. printk("msp3410: thread: sleepn");
  907. interruptible_sleep_on(&msp->wq);
  908. if (debug > 1)
  909. printk("msp3410: thread: wakeupn");
  910. if (msp->rmmod || signal_pending(current))
  911. goto done;
  912. if (msp->mode == MSP_MODE_EXTERN)
  913. continue;
  914. msp->active = 1;
  915. if (msp->watch_stereo) {
  916. watch_stereo(client);
  917. msp->active = 0;
  918. continue;
  919. }
  920. /* some time for the tuner to sync */
  921. current->state   = TASK_INTERRUPTIBLE;
  922. schedule_timeout(HZ/5);
  923. if (signal_pending(current))
  924. goto done;
  925. restart:
  926. if (msp->mode == MSP_MODE_EXTERN)
  927. continue;
  928. msp->restart = 0;
  929. del_timer(&msp->wake_stereo);
  930. msp->watch_stereo = 0;
  931. /* put into sane state (and mute) */
  932. msp3400c_reset(client);
  933. /* start autodetect */
  934. switch (msp->norm) {
  935. case VIDEO_MODE_PAL:
  936. mode = 0x1003;
  937. std  = 1;
  938. break;
  939. case VIDEO_MODE_NTSC:  /* BTSC */
  940. mode = 0x2003;
  941. std  = 0x0020;
  942. break;
  943. case VIDEO_MODE_SECAM: 
  944. mode = 0x0003;
  945. std  = 1;
  946. break;
  947. case VIDEO_MODE_RADIO: 
  948. mode = 0x0003;
  949. std  = 0x0040;
  950. break;
  951. default:
  952. mode = 0x0003;
  953. std  = 1;
  954. break;
  955. }
  956. msp3400c_write(client, I2C_MSP3400C_DEM, 0x30, mode);
  957. msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, std);
  958. if (debug) {
  959. int i;
  960. for (i = 0; modelist[i].name != NULL; i++)
  961. if (modelist[i].retval == std)
  962. break;
  963. printk("msp3410: setting mode: %s (0x%04x)n",
  964.        modelist[i].name ? modelist[i].name : "unknown",std);
  965. }
  966. if (std != 1) {
  967. /* programmed some specific mode */
  968. val = std;
  969. } else {
  970. /* triggered autodetect */
  971. for (;;) {
  972. current->state   = TASK_INTERRUPTIBLE;
  973. schedule_timeout(HZ/10);
  974. if (signal_pending(current))
  975. goto done;
  976. if (msp->restart)
  977. goto restart;
  978. /* check results */
  979. val = msp3400c_read(client, I2C_MSP3400C_DEM, 0x7e);
  980. if (val < 0x07ff)
  981. break;
  982. dprintk("msp3410: detection still in progressn");
  983. }
  984. }
  985. for (i = 0; modelist[i].name != NULL; i++)
  986. if (modelist[i].retval == val)
  987. break;
  988. dprintk("msp3410: current mode: %s (0x%04x)n",
  989. modelist[i].name ? modelist[i].name : "unknown",
  990. val);
  991. msp->main   = modelist[i].main;
  992. msp->second = modelist[i].second;
  993. if (amsound && (msp->norm == VIDEO_MODE_SECAM) && (val != 0x0009)) {
  994. /* autodetection has failed, let backup */
  995. dprintk("msp3410: autodetection failed, switching to backup mode: %s (0x%04x)n",
  996. modelist[8].name ? modelist[8].name : "unknown",val);
  997. val = 0x0009;
  998. msp3400c_write(client, I2C_MSP3400C_DEM, 0x20, val);
  999. }
  1000. /* set various prescales */
  1001. msp3400c_write(client, I2C_MSP3400C_DFP, 0x0d, 0x1900); /* scart */
  1002. msp3400c_write(client, I2C_MSP3400C_DFP, 0x0e, 0x2403); /* FM */
  1003. msp3400c_write(client, I2C_MSP3400C_DFP, 0x10, 0x5a00); /* nicam */
  1004. /* set stereo */
  1005. switch (val) {
  1006. case 0x0008: /* B/G NICAM */
  1007. case 0x000a: /* I NICAM */
  1008. if (val == 0x0008)
  1009. msp->mode = MSP_MODE_FM_NICAM1;
  1010. else
  1011. msp->mode = MSP_MODE_FM_NICAM2;
  1012. /* just turn on stereo */
  1013. msp->stereo = VIDEO_SOUND_STEREO;
  1014. msp->nicam_on = 1;
  1015. msp->watch_stereo = 1;
  1016. msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
  1017. break;
  1018. case 0x0009:
  1019. msp->mode = MSP_MODE_AM_NICAM;
  1020. msp->stereo = VIDEO_SOUND_MONO;
  1021. msp->nicam_on = 1;
  1022. msp3400c_setstereo(client,VIDEO_SOUND_MONO);
  1023. msp->watch_stereo = 1;
  1024. break;
  1025. case 0x0020: /* BTSC */
  1026. /* just turn on stereo */
  1027. msp->mode   = MSP_MODE_BTSC;
  1028. msp->stereo = VIDEO_SOUND_STEREO;
  1029. msp->nicam_on = 0;
  1030. msp->watch_stereo = 1;
  1031. msp3400c_setstereo(client,VIDEO_SOUND_STEREO);
  1032. break;
  1033. case 0x0040: /* FM radio */
  1034. msp->mode   = MSP_MODE_FM_RADIO;
  1035. msp->stereo = VIDEO_SOUND_STEREO;
  1036. msp->nicam_on = 0;
  1037. msp->watch_stereo = 0;
  1038. /* scart routing */
  1039. msp3400c_set_scart(client,SCART_IN2,0);
  1040. msp3400c_write(client,I2C_MSP3400C_DFP, 0x08, 0x0220);
  1041. msp3400c_write(client,I2C_MSP3400C_DFP, 0x09, 0x0220);
  1042. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0b, 0x0220);
  1043. break;
  1044. case 0x0003:
  1045. msp->mode   = MSP_MODE_FM_TERRA;
  1046. msp->stereo = VIDEO_SOUND_MONO;
  1047. msp->nicam_on = 0;
  1048. msp->watch_stereo = 1;
  1049. break;
  1050. }
  1051. /* unmute + restore dfp registers */
  1052. msp3400c_setbass(client, msp->bass);
  1053. msp3400c_settreble(client, msp->treble);
  1054. msp3400c_setvolume(client, msp->muted, msp->left, msp->right);
  1055. msp3400c_restore_dfp(client);
  1056. if (msp->watch_stereo)
  1057. mod_timer(&msp->wake_stereo, jiffies+HZ);
  1058. msp->active = 0;
  1059. }
  1060. done:
  1061. dprintk("msp3410: thread: exitn");
  1062. msp->active = 0;
  1063. msp->thread = NULL;
  1064. if(msp->notify != NULL)
  1065. up(msp->notify);
  1066. return 0;
  1067. }
  1068. /* ----------------------------------------------------------------------- */
  1069. static int msp_attach(struct i2c_adapter *adap, int addr,
  1070.       unsigned short flags, int kind);
  1071. static int msp_detach(struct i2c_client *client);
  1072. static int msp_probe(struct i2c_adapter *adap);
  1073. static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg);
  1074. static struct i2c_driver driver = {
  1075.         name:           "i2c msp3400 driver",
  1076.         id:             I2C_DRIVERID_MSP3400,
  1077.         flags:          I2C_DF_NOTIFY,
  1078.         attach_adapter: msp_probe,
  1079.         detach_client:  msp_detach,
  1080.         command:        msp_command,
  1081. };
  1082. static struct i2c_client client_template = 
  1083. {
  1084. name:   "(unset)",
  1085. flags:  I2C_CLIENT_ALLOW_USE,
  1086.         driver: &driver,
  1087. };
  1088. static int msp_attach(struct i2c_adapter *adap, int addr,
  1089.       unsigned short flags, int kind)
  1090. {
  1091. DECLARE_MUTEX_LOCKED(sem);
  1092. struct msp3400c *msp;
  1093.         struct i2c_client *c;
  1094. int              rev1,rev2,i;
  1095.         client_template.adapter = adap;
  1096.         client_template.addr = addr;
  1097.         if (-1 == msp3400c_reset(&client_template)) {
  1098.                 dprintk("msp3400: no chip foundn");
  1099.                 return -1;
  1100.         }
  1101.         if (NULL == (c = kmalloc(sizeof(struct i2c_client),GFP_KERNEL)))
  1102.                 return -ENOMEM;
  1103.         memcpy(c,&client_template,sizeof(struct i2c_client));
  1104. if (NULL == (msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL))) {
  1105. kfree(c);
  1106. return -ENOMEM;
  1107. }
  1108. memset(msp,0,sizeof(struct msp3400c));
  1109. msp->left   = 65535;
  1110. msp->right  = 65535;
  1111. msp->bass   = 32768;
  1112. msp->treble = 32768;
  1113. msp->input  = -1;
  1114. for (i = 0; i < DFP_COUNT; i++)
  1115. msp->dfp_regs[i] = -1;
  1116. c->data = msp;
  1117. init_waitqueue_head(&msp->wq);
  1118. if (-1 == msp3400c_reset(c)) {
  1119. kfree(msp);
  1120. kfree(c);
  1121. dprintk("msp3400: no chip foundn");
  1122. return -1;
  1123. }
  1124.     
  1125. rev1 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1e);
  1126. if (-1 != rev1)
  1127. rev2 = msp3400c_read(c, I2C_MSP3400C_DFP, 0x1f);
  1128. if ((-1 == rev1) || (0 == rev1 && 0 == rev2)) {
  1129. kfree(msp);
  1130. kfree(c);
  1131. printk("msp3400: error while reading chip versionn");
  1132. return -1;
  1133. }
  1134. #if 0
  1135. /* this will turn on a 1kHz beep - might be useful for debugging... */
  1136. msp3400c_write(client,I2C_MSP3400C_DFP, 0x0014, 0x1040);
  1137. #endif
  1138. sprintf(c->name,"MSP34%02d%c-%c%d",
  1139. (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
  1140. msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0;
  1141. if (simple == -1) {
  1142. /* default mode */
  1143. /* msp->simple = (((rev2>>8)&0xff) == 0) ? 0 : 1; */
  1144. msp->simple = ((rev1&0xff)+'@' > 'C');
  1145. } else {
  1146. /* use insmod option */
  1147. msp->simple = simple;
  1148. }
  1149. /* timer for stereo checking */
  1150. msp->wake_stereo.function = msp3400c_stereo_wake;
  1151. msp->wake_stereo.data     = (unsigned long)msp;
  1152. /* hello world :-) */
  1153. printk(KERN_INFO "msp34xx: init: chip=%s",c->name);
  1154. if (msp->nicam)
  1155. printk(", has NICAM support");
  1156. printk("n");
  1157. /* startup control thread */
  1158. MOD_INC_USE_COUNT;
  1159. msp->notify = &sem;
  1160. kernel_thread(msp->simple ? msp3410d_thread : msp3400c_thread,
  1161.       (void *)c, 0);
  1162. down(&sem);
  1163. msp->notify = NULL;
  1164. wake_up_interruptible(&msp->wq);
  1165. /* update our own array */
  1166. for (i = 0; i < MSP3400_MAX; i++) {
  1167. if (NULL == msps[i]) {
  1168. msps[i] = c;
  1169. break;
  1170. }
  1171. }
  1172. /* done */
  1173.         i2c_attach_client(c);
  1174. return 0;
  1175. }
  1176. static int msp_detach(struct i2c_client *client)
  1177. {
  1178. DECLARE_MUTEX_LOCKED(sem);
  1179. struct msp3400c *msp  = (struct msp3400c*)client->data;
  1180. int i;
  1181. /* shutdown control thread */
  1182. del_timer(&msp->wake_stereo);
  1183. if (msp->thread) 
  1184. {
  1185. msp->notify = &sem;
  1186. msp->rmmod = 1;
  1187. wake_up_interruptible(&msp->wq);
  1188. down(&sem);
  1189. msp->notify = NULL;
  1190. }
  1191.      msp3400c_reset(client);
  1192.         /* update our own array */
  1193. for (i = 0; i < MSP3400_MAX; i++) {
  1194. if (client == msps[i]) {
  1195. msps[i] = NULL;
  1196. break;
  1197. }
  1198. }
  1199. i2c_detach_client(client);
  1200. kfree(msp);
  1201. kfree(client);
  1202. MOD_DEC_USE_COUNT;
  1203. return 0;
  1204. }
  1205. static int msp_probe(struct i2c_adapter *adap)
  1206. {
  1207. if (adap->id == (I2C_ALGO_BIT | I2C_HW_B_BT848))
  1208. return i2c_probe(adap, &addr_data, msp_attach);
  1209. return 0;
  1210. }
  1211. static void msp_wake_thread(struct i2c_client *client)
  1212. {
  1213. struct msp3400c *msp  = (struct msp3400c*)client->data;
  1214. msp3400c_setvolume(client,msp->muted,0,0);
  1215. msp->watch_stereo=0;
  1216. del_timer(&msp->wake_stereo);
  1217. if (msp->active)
  1218. msp->restart = 1;
  1219. wake_up_interruptible(&msp->wq);
  1220. }
  1221. static int msp_command(struct i2c_client *client, unsigned int cmd, void *arg)
  1222. {
  1223. struct msp3400c *msp  = (struct msp3400c*)client->data;
  1224.         __u16           *sarg = arg;
  1225. #if 0
  1226. int             *iarg = (int*)arg;
  1227. #endif
  1228. switch (cmd) {
  1229. case AUDC_SET_INPUT:
  1230. /* scart switching
  1231.      - IN1 is often used for external input
  1232.      - Hauppauge uses IN2 for the radio */
  1233. dprintk(KERN_DEBUG "msp34xx: AUDC_SET_INPUT(%d)n",*sarg);
  1234. if (*sarg == msp->input)
  1235. break;
  1236. msp->input = *sarg;
  1237. switch (*sarg) {
  1238. case AUDIO_RADIO:
  1239. msp->mode   = MSP_MODE_FM_RADIO;
  1240. msp->stereo = VIDEO_SOUND_STEREO;
  1241. msp3400c_set_scart(client,SCART_IN2,0);
  1242. msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
  1243. msp3400c_setstereo(client,msp->stereo);
  1244. break;
  1245. case AUDIO_EXTERN:
  1246. msp->mode   = MSP_MODE_EXTERN;
  1247. msp->stereo = VIDEO_SOUND_STEREO;
  1248. msp3400c_set_scart(client,SCART_IN1,0);
  1249. msp3400c_write(client,I2C_MSP3400C_DFP,0x000d,0x1900);
  1250. msp3400c_setstereo(client,msp->stereo);
  1251. break;
  1252. case AUDIO_TUNER:
  1253. msp->mode   = -1;
  1254. msp_wake_thread(client);
  1255. break;
  1256. default:
  1257. if (*sarg & AUDIO_MUTE)
  1258. msp3400c_set_scart(client,SCART_MUTE,0);
  1259. break;
  1260. }
  1261. if (msp->active)
  1262. msp->restart = 1;
  1263. break;
  1264. case AUDC_SET_RADIO:
  1265. dprintk(KERN_DEBUG "msp34xx: AUDC_SET_RADIOn");
  1266. msp->norm = VIDEO_MODE_RADIO;
  1267. msp->watch_stereo=0;
  1268. del_timer(&msp->wake_stereo);
  1269. dprintk("msp34xx: switching to radio moden");
  1270. if (msp->simple) {
  1271. /* the thread will do for us */
  1272. msp_wake_thread(client);
  1273. } else {
  1274. /* set msp3400 to FM radio mode */
  1275. msp3400c_setmode(client,MSP_MODE_FM_RADIO);
  1276. msp3400c_setcarrier(client, MSP_CARRIER(10.7),MSP_CARRIER(10.7));
  1277. msp3400c_setvolume(client,msp->muted,msp->left,msp->right);
  1278. }
  1279. if (msp->active)
  1280. msp->restart = 1;
  1281. break;
  1282. #if 1
  1283. /* work-in-progress:  hook to control the DFP registers */
  1284. case MSP_SET_DFPREG:
  1285. {
  1286. struct msp_dfpreg *r = arg;
  1287. int i;
  1288. if (r->reg < 0 || r->reg >= DFP_COUNT)
  1289. return -EINVAL;
  1290. for (i = 0; i < sizeof(bl_dfp)/sizeof(int); i++)
  1291. if (r->reg == bl_dfp[i])
  1292. return -EINVAL;
  1293. msp->dfp_regs[r->reg] = r->value;
  1294. msp3400c_write(client,I2C_MSP3400C_DFP,r->reg,r->value);
  1295. return 0;
  1296. }
  1297. case MSP_GET_DFPREG:
  1298. {
  1299. struct msp_dfpreg *r = arg;
  1300. if (r->reg < 0 || r->reg >= DFP_COUNT)
  1301. return -EINVAL;
  1302. r->value = msp3400c_read(client,I2C_MSP3400C_DFP,r->reg);
  1303. return 0;
  1304. }
  1305. #endif
  1306. /* --- v4l ioctls --- */
  1307. /* take care: bttv does userspace copying, we'll get a
  1308.    kernel pointer here... */
  1309. case VIDIOCGAUDIO:
  1310. {
  1311. struct video_audio *va = arg;
  1312. dprintk(KERN_DEBUG "msp34xx: VIDIOCGAUDIOn");
  1313. va->flags |= VIDEO_AUDIO_VOLUME |
  1314. VIDEO_AUDIO_BASS |
  1315. VIDEO_AUDIO_TREBLE |
  1316. VIDEO_AUDIO_MUTABLE;
  1317. if (msp->muted)
  1318. va->flags |= VIDEO_AUDIO_MUTE;
  1319. va->volume=MAX(msp->left,msp->right);
  1320. va->balance=(32768*MIN(msp->left,msp->right))/
  1321. (va->volume ? va->volume : 1);
  1322. va->balance=(msp->left<msp->right)?
  1323. (65535-va->balance) : va->balance;
  1324. if (0 == va->volume)
  1325. va->balance = 32768;
  1326. va->bass = msp->bass;
  1327. va->treble = msp->treble;
  1328. if (msp->norm != VIDEO_MODE_RADIO) {
  1329. autodetect_stereo(client);
  1330. va->mode = msp->stereo;
  1331. }
  1332. break;
  1333. }
  1334. case VIDIOCSAUDIO:
  1335. {
  1336. struct video_audio *va = arg;
  1337. dprintk(KERN_DEBUG "msp34xx: VIDIOCSAUDIOn");
  1338. msp->muted = (va->flags & VIDEO_AUDIO_MUTE);
  1339. msp->left = (MIN(65536 - va->balance,32768) *
  1340.      va->volume) / 32768;
  1341. msp->right = (MIN(va->balance,32768) *
  1342.       va->volume) / 32768;
  1343. msp->bass = va->bass;
  1344. msp->treble = va->treble;
  1345. msp3400c_setvolume(client,msp->muted,msp->left,msp->right);
  1346. msp3400c_setbass(client,msp->bass);
  1347. msp3400c_settreble(client,msp->treble);
  1348. if (va->mode != 0) {
  1349. msp->watch_stereo=0;
  1350. del_timer(&msp->wake_stereo);
  1351. msp->stereo = va->mode;
  1352. msp3400c_setstereo(client,va->mode);
  1353. }
  1354. break;
  1355. }
  1356. case VIDIOCSCHAN:
  1357. {
  1358. struct video_channel *vc = arg;
  1359. dprintk(KERN_DEBUG "msp34xx: VIDIOCSCHANn");
  1360. dprintk("msp34xx: switching to TV moden");
  1361. msp->norm = vc->norm;
  1362. break;
  1363. }
  1364. case VIDIOCSFREQ:
  1365. {
  1366. /* new channel -- kick audio carrier scan */
  1367. dprintk(KERN_DEBUG "msp34xx: VIDIOCSFREQn");
  1368. msp_wake_thread(client);
  1369. break;
  1370. }
  1371. default:
  1372. /* nothing */
  1373. break;
  1374. }
  1375. return 0;
  1376. }
  1377. /* ----------------------------------------------------------------------- */
  1378. static int msp3400_init_module(void)
  1379. {
  1380. i2c_add_driver(&driver);
  1381. return 0;
  1382. }
  1383. static void msp3400_cleanup_module(void)
  1384. {
  1385. i2c_del_driver(&driver);
  1386. }
  1387. module_init(msp3400_init_module);
  1388. module_exit(msp3400_cleanup_module);
  1389. /*
  1390.  * Overrides for Emacs so that we follow Linus's tabbing style.
  1391.  * ---------------------------------------------------------------------------
  1392.  * Local variables:
  1393.  * c-basic-offset: 8
  1394.  * End:
  1395.  */