msp3400.c
上传用户:aoeyumen
上传日期:2007-01-06
资源大小:3329k
文件大小:32k
源码类别:

DVD

开发平台:

Unix_Linux

  1. /*
  2.  * programming the msp34* sound processor family
  3.  *
  4.  * (c) 1997,1998 Gerd Knorr <kraxel@goldbach.in-berlin.de>
  5.  *
  6.  * what works and what doesn't:
  7.  *
  8.  *  AM-Mono
  9.  *      probably doesn't (untested)
  10.  *
  11.  *  FM-Mono
  12.  *      should work. The stereo modes are backward compatible to FM-mono,
  13.  *      therefore FM-Mono should be allways available.
  14.  *
  15.  *  FM-Stereo (B/G, used in germany)
  16.  *      should work, with autodetect
  17.  *
  18.  *  FM-Stereo (satellite)
  19.  *      should work, no autodetect (i.e. default is mono, but you can
  20.  *      switch to stereo -- untested)
  21.  *
  22.  *  NICAM (B/G, used in UK, Scandinavia and Spain)
  23.  *      should work, with autodetect. Support for NICAM was added by
  24.  *      Pekka Pietikainen <pp@netppl.fi>
  25.  *
  26.  *
  27.  * TODO:
  28.  *   - better SAT support
  29.  *
  30.  *
  31.  * 980623  Thomas Sailer (sailer@ife.ee.ethz.ch)
  32.  *         using soundcore instead of OSS
  33.  *
  34.  */
  35. #include <linux/module.h>
  36. #include <linux/version.h>
  37. #include <linux/kernel.h>
  38. #include <linux/sched.h>
  39. #include <linux/string.h>
  40. #include <linux/timer.h>
  41. #include <linux/delay.h>
  42. #include <linux/errno.h>
  43. #include <linux/malloc.h>
  44. #ifdef __SMP__
  45. #include <asm/pgtable.h>
  46. #include <linux/smp_lock.h>
  47. #endif
  48. /* kernel_thread */
  49. #define __KERNEL_SYSCALLS__
  50. #include <linux/unistd.h>
  51. #include <linux/i2c.h>
  52. #include <linux/videodev.h>
  53. #include "msp3400.h"
  54. /* sound mixer stuff */ 
  55. #include <linux/config.h>
  56. #if LINUX_VERSION_CODE > 0x020140 /* need modular sound driver */
  57. # if defined(CONFIG_SOUND) || defined(CONFIG_SOUND_MODULE)
  58. #  define REGISTER_MIXER 1
  59. # endif
  60. #endif
  61. #undef REGISTER_MIXER
  62. static int debug = 0; /* insmod parameter */
  63. struct msp3400c {
  64. struct i2c_bus     *bus;
  65. int nicam;
  66. int mode;
  67. int norm;
  68. int stereo;
  69. int main, second; /* sound carrier */
  70. int left, right; /* volume */
  71. int bass, treble;
  72. /* thread */
  73. struct task_struct  *thread;
  74. struct wait_queue   *wq;
  75. struct semaphore    *notify;
  76. int                  active,restart,rmmod;
  77. int                  watch_stereo;
  78. struct timer_list    wake_stereo;
  79. };
  80. #define VIDEO_MODE_RADIO 16      /* norm magic for radio mode */
  81. /* ---------------------------------------------------------------------- */
  82. #define dprintk     if (debug) printk
  83. #if LINUX_VERSION_CODE < 0x020100
  84. /* 2.0.x */
  85. #define signal_pending(current)  (current->signal & ~current->blocked)
  86. #define sigfillset(set)
  87. #define mdelay(x) udelay(1000*x)
  88. #else
  89. MODULE_PARM(debug,"i");
  90. #endif
  91. #if LINUX_VERSION_CODE < 0x02017f
  92. void schedule_timeout(int j)
  93. {
  94. current->timeout = jiffies + j;
  95. schedule();
  96. }
  97. #endif
  98. /* ---------------------------------------------------------------------- */
  99. #define I2C_MSP3400C       0x80
  100. #define I2C_MSP3400C_DEM   0x10
  101. #define I2C_MSP3400C_DFP   0x12
  102. /* ----------------------------------------------------------------------- */
  103. /* functions for talking to the MSP3400C Sound processor                   */
  104. static int msp3400c_reset(struct i2c_bus *bus)
  105. {
  106. int ret = 0;
  107.     
  108. mdelay(2);
  109. i2c_start(bus);
  110. i2c_sendbyte(bus, I2C_MSP3400C,2000);
  111. i2c_sendbyte(bus, 0x00,0);
  112. i2c_sendbyte(bus, 0x80,0);
  113. i2c_sendbyte(bus, 0x00,0);
  114. i2c_stop(bus);
  115. mdelay(2);
  116. i2c_start(bus);
  117. if (0 != i2c_sendbyte(bus, I2C_MSP3400C,2000) ||
  118.     0 != i2c_sendbyte(bus, 0x00,0) ||
  119.     0 != i2c_sendbyte(bus, 0x00,0) ||
  120.     0 != i2c_sendbyte(bus, 0x00,0)) {
  121. ret = -1;
  122. printk(KERN_ERR "msp3400: chip reset failed, penguin on i2c bus?n");
  123. }
  124. i2c_stop(bus);
  125. mdelay(2);
  126. return ret;
  127. }
  128. static int
  129. msp3400c_read(struct i2c_bus *bus, int dev, int addr)
  130. {
  131. int ret=0;
  132. short val = 0;
  133. i2c_start(bus);
  134. if (0 != i2c_sendbyte(bus, I2C_MSP3400C,2000) ||
  135.     0 != i2c_sendbyte(bus, dev+1,       0)    ||
  136.     0 != i2c_sendbyte(bus, addr >> 8,   0)    ||
  137.     0 != i2c_sendbyte(bus, addr & 0xff, 0)) {
  138. ret = -1;
  139. } else {
  140. i2c_start(bus);
  141. if (0 != i2c_sendbyte(bus, I2C_MSP3400C+1,2000)) {
  142. ret = -1;
  143. } else {
  144. val |= (int)i2c_readbyte(bus,0) << 8;
  145. val |= (int)i2c_readbyte(bus,1);
  146. }
  147. }
  148. i2c_stop(bus);
  149. if (-1 == ret) {
  150. printk(KERN_WARNING "msp3400: I/O error, trying reset (read %s 0x%x)n",
  151.        (dev == I2C_MSP3400C_DEM) ? "Demod" : "Audio", addr);
  152. msp3400c_reset(bus);
  153. }
  154. return val;
  155. }
  156. static int
  157. msp3400c_write(struct i2c_bus *bus, int dev, int addr, int val)
  158. {
  159. int ret = 0;
  160.     
  161. i2c_start(bus);
  162. if (0 != i2c_sendbyte(bus, I2C_MSP3400C,2000) ||
  163.     0 != i2c_sendbyte(bus, dev,         0)    ||
  164.     0 != i2c_sendbyte(bus, addr >> 8,   0)    ||
  165.     0 != i2c_sendbyte(bus, addr & 0xff, 0)    ||
  166.     0 != i2c_sendbyte(bus, val >> 8,    0)    ||
  167.     0 != i2c_sendbyte(bus, val & 0xff,  0))
  168. ret = -1;
  169. i2c_stop(bus);
  170. if (-1 == ret) {
  171. printk(KERN_WARNING "msp3400: I/O error, trying reset (write %s 0x%x)n",
  172.        (dev == I2C_MSP3400C_DEM) ? "Demod" : "Audio", addr);
  173. msp3400c_reset(bus);
  174. }
  175. return ret;
  176. }
  177. /* ------------------------------------------------------------------------ */
  178. /* This macro is allowed for *constants* only, gcc must calculate it
  179.    at compile time.  Remember -- no floats in kernel mode */
  180. #define MSP_CARRIER(freq) ((int)((float)(freq/18.432)*(1<<24)))
  181. #define MSP_MODE_AM_DETECT   0
  182. #define MSP_MODE_FM_RADIO    2
  183. #define MSP_MODE_FM_TERRA    3
  184. #define MSP_MODE_FM_SAT      4
  185. #define MSP_MODE_FM_NICAM1   5
  186. #define MSP_MODE_FM_NICAM2   6
  187. static struct MSP_INIT_DATA_DEM {
  188. int fir1[6];
  189. int fir2[6];
  190. int cdo1;
  191. int cdo2;
  192. int ad_cv;
  193. int mode_reg;
  194. int dfp_src;
  195. int dfp_matrix;
  196. } msp_init_data[] = {
  197. /* AM (for carrier detect / msp3400) */
  198. { { 75, 19, 36, 35, 39, 40 }, { 75, 19, 36, 35, 39, 40 },
  199.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  200.   0x00d0, 0x0500,   0x0020, 0x3000},
  201. /* AM (for carrier detect / msp3410) */
  202. { { -1, -1, -8, 2, 59, 126 }, { -1, -1, -8, 2, 59, 126 },
  203.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  204.   0x00d0, 0x0100,   0x0020, 0x3000},
  205. /* FM Radio */
  206. { { -8, -8, 4, 6, 78, 107 }, { -8, -8, 4, 6, 78, 107 },
  207.   MSP_CARRIER(10.7), MSP_CARRIER(10.7),
  208.   0x00d0, 0x0480, 0x0020, 0x3000 },
  209. /* Terrestial FM-mono + FM-stereo */
  210. { {  3, 18, 27, 48, 66, 72 }, {  3, 18, 27, 48, 66, 72 },
  211.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  212.   0x00d0, 0x0480,   0x0030, 0x3000},
  213. /* Sat FM-mono */
  214. { {  1,  9, 14, 24, 33, 37 }, {  3, 18, 27, 48, 66, 72 },
  215.   MSP_CARRIER(6.5), MSP_CARRIER(6.5),
  216.   0x00c6, 0x0480,   0x0000, 0x3000},
  217. /* NICAM B/G, D/K */
  218. { { -2, -8, -10, 10, 50, 86 }, {  3, 18, 27, 48, 66, 72 },
  219.   MSP_CARRIER(5.5), MSP_CARRIER(5.5),
  220.   0x00d0, 0x0040,   0x0120, 0x3000},
  221. /* NICAM I */
  222. { {  2, 4, -6, -4, 40, 94 }, {  3, 18, 27, 48, 66, 72 },
  223.   MSP_CARRIER(6.0), MSP_CARRIER(6.0),
  224.   0x00d0, 0x0040,   0x0120, 0x3000},
  225. };
  226. struct CARRIER_DETECT {
  227. int   cdo;
  228. char *name;
  229. };
  230. static struct CARRIER_DETECT carrier_detect_main[] = {
  231. /* main carrier */
  232. { MSP_CARRIER(4.5),        "4.5   NTSC"                   }, 
  233. { MSP_CARRIER(5.5),        "5.5   PAL B/G"                }, 
  234. { MSP_CARRIER(6.0),        "6.0   PAL I"                  },
  235. { MSP_CARRIER(6.5),        "6.5   PAL D/K + SAT + SECAM"  }
  236. };
  237. static struct CARRIER_DETECT carrier_detect_55[] = {
  238. /* PAL B/G */
  239. { MSP_CARRIER(5.7421875),  "5.742 PAL B/G FM-stereo"     }, 
  240. { MSP_CARRIER(5.85),       "5.85  PAL B/G NICAM"         }
  241. };
  242. static struct CARRIER_DETECT carrier_detect_65[] = {
  243. /* PAL SAT / SECAM */
  244. { MSP_CARRIER(5.85),       "5.85  PAL D/K NICAM" },
  245. { MSP_CARRIER(6.2578125),  "6.25  PAL D/K1 FM-stereo" },
  246. { MSP_CARRIER(6.7421875),  "6.74  PAL D/K2 FM-stereo" },
  247. { MSP_CARRIER(7.02),       "7.02  PAL SAT FM-stereo s/b" },
  248. { MSP_CARRIER(7.20),       "7.20  PAL SAT FM-stereo s"   },
  249. { MSP_CARRIER(7.38),       "7.38  PAL SAT FM-stereo b"   },
  250. };
  251. #define CARRIER_COUNT(x) (sizeof(x)/sizeof(struct CARRIER_DETECT))
  252. /* ------------------------------------------------------------------------ */
  253. static void msp3400c_setcarrier(struct i2c_bus *bus, int cdo1, int cdo2)
  254. {
  255. msp3400c_write(bus,I2C_MSP3400C_DEM, 0x0093, cdo1 & 0xfff);
  256. msp3400c_write(bus,I2C_MSP3400C_DEM, 0x009b, cdo1 >> 12);
  257. msp3400c_write(bus,I2C_MSP3400C_DEM, 0x00a3, cdo2 & 0xfff);
  258. msp3400c_write(bus,I2C_MSP3400C_DEM, 0x00ab, cdo2 >> 12);
  259. msp3400c_write(bus,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
  260. }
  261. static void msp3400c_setvolume(struct i2c_bus *bus, int left, int right)
  262. {
  263. int vol,val,balance;
  264. vol     = (left > right) ? left : right;
  265. val     = (vol * 0x73 / 65535) << 8;
  266. balance = 0;
  267. if (vol > 0)
  268. balance = ((right-left) * 127) / vol;
  269. dprintk("msp3400: setvolume: %d:%d 0x%02x 0x%02xn",
  270. left,right,val>>8,balance);
  271. msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0000, val); /* loudspeaker */
  272. msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0006, val); /* headphones  */
  273. /* scart - on/off only */
  274. msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0007, val ? 0x4000 : 0);
  275. msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0001, balance << 8);
  276. }
  277. static void msp3400c_setbass(struct i2c_bus *bus, int bass)
  278. {
  279. int val = ((bass-32768) * 0x60 / 65535) << 8;
  280. dprintk("msp3400: setbass: %d 0x%02xn",bass, val>>8);
  281. msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0002, val); /* loudspeaker */
  282. }
  283. static void msp3400c_settreble(struct i2c_bus *bus, int treble)
  284. {
  285. int val = ((treble-32768) * 0x60 / 65535) << 8;
  286. dprintk("msp3400: settreble: %d 0x%02xn",treble, val>>8);
  287. msp3400c_write(bus,I2C_MSP3400C_DFP, 0x0003, val); /* loudspeaker */
  288. }
  289. static void msp3400c_setmode(struct msp3400c *msp, int type)
  290. {
  291. int i;
  292. dprintk("msp3400: setmode: %dn",type);
  293. msp->mode   = type;
  294. msp->stereo = VIDEO_SOUND_MONO;
  295. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x00bb,          /* ad_cv */
  296.        msp_init_data[type].ad_cv);
  297.     
  298. for (i = 5; i >= 0; i--)                                   /* fir 1 */
  299. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0001,
  300.        msp_init_data[type].fir1[i]);
  301.     
  302. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0005, 0x0004); /* fir 2 */
  303. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0005, 0x0040);
  304. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0005, 0x0000);
  305. for (i = 5; i >= 0; i--)
  306. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0005,
  307.        msp_init_data[type].fir2[i]);
  308.     
  309. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0083,     /* MODE_REG */
  310.        msp_init_data[type].mode_reg);
  311.     
  312. msp3400c_setcarrier(msp->bus, msp_init_data[type].cdo1,
  313.     msp_init_data[type].cdo2);
  314.     
  315. msp3400c_write(msp->bus,I2C_MSP3400C_DEM, 0x0056, 0); /*LOAD_REG_1/2*/
  316. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,
  317.        msp_init_data[type].dfp_src);
  318. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,
  319.        msp_init_data[type].dfp_src);
  320. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,
  321.        msp_init_data[type].dfp_src);
  322. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000e,
  323.        msp_init_data[type].dfp_matrix);
  324. if (msp->nicam) {
  325. /* msp3410 needs some more initialization */
  326. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0010, 0x3000);
  327. }
  328. }
  329. static void msp3400c_setstereo(struct msp3400c *msp, int mode)
  330. {
  331. int nicam=0; /* channel source: FM/AM or nicam */
  332. /* switch demodulator */
  333. switch (msp->mode) {
  334. case MSP_MODE_FM_TERRA:
  335. dprintk("msp3400: FM setstereo: %dn",mode);
  336. msp->stereo = mode;
  337. msp3400c_setcarrier(msp->bus,msp->second,msp->main);
  338. switch (mode) {
  339. case VIDEO_SOUND_STEREO:
  340. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000e, 0x3001);
  341. break;
  342. case VIDEO_SOUND_MONO:
  343. case VIDEO_SOUND_LANG1:
  344. case VIDEO_SOUND_LANG2:
  345. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000e, 0x3000);
  346. break;
  347. }
  348. break;
  349. case MSP_MODE_FM_SAT:
  350. dprintk("msp3400: SAT setstereo: %dn",mode);
  351. msp->stereo = mode;
  352. switch (mode) {
  353. case VIDEO_SOUND_MONO:
  354. msp3400c_setcarrier(msp->bus, MSP_CARRIER(6.5), MSP_CARRIER(6.5));
  355. break;
  356. case VIDEO_SOUND_STEREO:
  357. msp3400c_setcarrier(msp->bus, MSP_CARRIER(7.2), MSP_CARRIER(7.02));
  358. break;
  359. case VIDEO_SOUND_LANG1:
  360. msp3400c_setcarrier(msp->bus, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
  361. break;
  362. case VIDEO_SOUND_LANG2:
  363. msp3400c_setcarrier(msp->bus, MSP_CARRIER(7.38), MSP_CARRIER(7.02));
  364. break;
  365. }
  366. break;
  367. case MSP_MODE_FM_NICAM1:
  368. case MSP_MODE_FM_NICAM2:
  369. dprintk("msp3400: NICAM setstereo: %dn",mode);
  370. msp->stereo = mode;
  371. msp3400c_setcarrier(msp->bus,msp->second,msp->main);
  372. nicam=0x0100;
  373. break;
  374. default:
  375. /* can't do stereo - abort here */
  376. return;
  377. }
  378. /* switch audio */
  379. switch (mode) {
  380. case VIDEO_SOUND_STEREO:
  381. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,0x0020|nicam);
  382. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,0x0020|nicam);
  383. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,0x0020|nicam);
  384. #if 0
  385. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0005,0x4000);
  386. #endif
  387. break;
  388. case VIDEO_SOUND_MONO:
  389. case VIDEO_SOUND_LANG1:
  390. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,0x0000|nicam);
  391. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,0x0000|nicam);
  392. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,0x0000|nicam);
  393. break;
  394. case VIDEO_SOUND_LANG2:
  395. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0008,0x0010|nicam);
  396. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0009,0x0010|nicam);
  397. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x000a,0x0010|nicam);
  398. break;
  399. }
  400. }
  401. static void
  402. msp3400c_print_mode(struct msp3400c *msp)
  403. {
  404. if (msp->main == msp->second) {
  405. printk("msp3400: mono sound carrier: %d.%03d MHzn",
  406.        msp->main/910000,(msp->main/910)%1000);
  407. } else {
  408. printk("msp3400: main sound carrier: %d.%03d MHzn",
  409.        msp->main/910000,(msp->main/910)%1000);
  410. }
  411. if (msp->mode == MSP_MODE_FM_NICAM1 ||
  412.     msp->mode == MSP_MODE_FM_NICAM2)
  413. printk("msp3400: NICAM carrier     : %d.%03d MHzn",
  414.        msp->second/910000,(msp->second/910)%1000);
  415. if (msp->mode == MSP_MODE_FM_TERRA &&
  416.     msp->main != msp->second) {
  417. printk("msp3400: FM-stereo carrier : %d.%03d MHzn",
  418.        msp->second/910000,(msp->second/910)%1000);
  419. }
  420. }
  421. /* ----------------------------------------------------------------------- */
  422. struct REGISTER_DUMP {
  423. int   addr;
  424. char *name;
  425. };
  426. struct REGISTER_DUMP d1[] = {
  427. { 0x007e, "autodetect" },
  428. { 0x0023, "C_AD_BITS " },
  429. { 0x0038, "ADD_BITS  " },
  430. { 0x003e, "CIB_BITS  " },
  431. { 0x0057, "ERROR_RATE" },
  432. };
  433. /*
  434.  * A kernel thread for msp3400 control -- we don't want to block the
  435.  * in the ioctl while doing the sound carrier & stereo detect
  436.  */
  437. static void msp3400c_stereo_wake(unsigned long data)
  438. {
  439. struct msp3400c *msp = (struct msp3400c*)data;   /* XXX alpha ??? */
  440. wake_up_interruptible(&msp->wq);
  441. }
  442. static int msp3400c_thread(void *data)
  443. {
  444. struct msp3400c *msp = data;
  445.     
  446. struct CARRIER_DETECT *cd;
  447. int                   count, max1,max2,val1,val2, val,this;
  448. int                   newstereo;
  449. LOCK_FLAGS;
  450.     
  451. #ifdef __SMP__
  452. lock_kernel();
  453. #endif
  454.     
  455. exit_mm(current);
  456. current->session = 1;
  457. current->pgrp = 1;
  458. sigfillset(&current->blocked);
  459. current->fs->umask = 0;
  460. strcpy(current->comm,"msp3400");
  461. msp->wq     = NULL;
  462. msp->thread = current;
  463. #ifdef __SMP__
  464. unlock_kernel();
  465. #endif
  466. dprintk("msp3400: thread: startn");
  467. if(msp->notify != NULL)
  468. up(msp->notify);
  469. for (;;) {
  470. if (msp->rmmod)
  471. goto done;
  472. if (debug > 1)
  473. printk("msp3400: thread: sleepn");
  474. interruptible_sleep_on(&msp->wq);
  475. if (debug > 1)
  476. printk("msp3400: thread: wakeupn");
  477. if (msp->rmmod || signal_pending(current))
  478. goto done;
  479. if (VIDEO_MODE_RADIO == msp->norm)
  480. continue;  /* nothing to do */
  481. msp->active = 1;
  482. if (msp->watch_stereo) {
  483. /* do that stereo/multilang handling */
  484. LOCK_I2C_BUS(msp->bus);
  485. newstereo = msp->stereo;
  486. switch (msp->mode) {
  487. case MSP_MODE_FM_TERRA:
  488. val = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x18);
  489. dprintk("msp3400: stereo detect register: %dn",val);
  490. if (val > 4096) {
  491. newstereo = VIDEO_SOUND_STEREO;
  492. } else if (val < -4096) {
  493. newstereo = VIDEO_SOUND_LANG1;
  494. } else {
  495. newstereo = VIDEO_SOUND_MONO;
  496. }
  497. break;
  498. case MSP_MODE_FM_NICAM1:
  499. case MSP_MODE_FM_NICAM2:
  500. val = msp3400c_read(msp->bus, I2C_MSP3400C_DEM, 0x23);
  501. switch ((val & 0x1e) >> 1)  {
  502. case 0:
  503. case 8:
  504. newstereo = VIDEO_SOUND_STEREO;
  505. break;
  506. default:
  507. newstereo = VIDEO_SOUND_MONO;
  508. break;
  509. }
  510. break;
  511. }
  512. if (msp->stereo != newstereo) {
  513. dprintk("msp3400: watch: stereo %d ==> %dn",
  514. msp->stereo,newstereo);
  515. msp3400c_setstereo(msp,newstereo);
  516. }
  517. UNLOCK_I2C_BUS(msp->bus);
  518. if (msp->watch_stereo) {
  519. del_timer(&msp->wake_stereo);
  520. msp->wake_stereo.expires = jiffies + 5*HZ;
  521. add_timer(&msp->wake_stereo);
  522. }
  523. msp->active = 0;
  524. continue;
  525. }
  526. restart:
  527. LOCK_I2C_BUS(msp->bus);
  528. msp3400c_setvolume(msp->bus, 0, 0);
  529. msp3400c_setmode(msp, MSP_MODE_AM_DETECT);
  530. val1 = val2 = 0;
  531. max1 = max2 = -1;
  532. del_timer(&msp->wake_stereo);
  533. msp->watch_stereo = 0;
  534. /* carrier detect pass #1 -- main carrier */
  535. cd = carrier_detect_main; count = CARRIER_COUNT(carrier_detect_main);
  536. for (this = 0; this < count; this++) {
  537. msp3400c_setcarrier(msp->bus, cd[this].cdo,cd[this].cdo);
  538. UNLOCK_I2C_BUS(msp->bus);
  539. current->state   = TASK_INTERRUPTIBLE;
  540. schedule_timeout(HZ/25);
  541. if (signal_pending(current))
  542. goto done;
  543. if (msp->restart) {
  544. msp->restart = 0;
  545. goto restart;
  546. }
  547. LOCK_I2C_BUS(msp->bus);
  548. val = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1b);
  549. if (val1 < val)
  550. val1 = val, max1 = this;
  551. dprintk("msp3400: carrier1 val: %5d / %sn", val,cd[this].name);
  552. }
  553. /* carrier detect pass #2 -- second (stereo) carrier */
  554. switch (max1) {
  555. case 1: /* 5.5 */
  556. cd = carrier_detect_55; count = CARRIER_COUNT(carrier_detect_55);
  557. break;
  558. case 3: /* 6.5 */
  559. cd = carrier_detect_65; count = CARRIER_COUNT(carrier_detect_65);
  560. break;
  561. case 0: /* 4.5 */
  562. case 2: /* 6.0 */
  563. default:
  564. cd = NULL; count = 0;
  565. break;
  566. }
  567. for (this = 0; this < count; this++) {
  568. msp3400c_setcarrier(msp->bus, cd[this].cdo,cd[this].cdo);
  569. UNLOCK_I2C_BUS(msp->bus);
  570. current->state   = TASK_INTERRUPTIBLE;
  571. schedule_timeout(HZ/25);
  572. if (signal_pending(current))
  573. goto done;
  574. if (msp->restart) {
  575. msp->restart = 0;
  576. goto restart;
  577. }
  578. LOCK_I2C_BUS(msp->bus);
  579. val = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1b);
  580. if (val2 < val)
  581. val2 = val, max2 = this;
  582. dprintk("msp3400: carrier2 val: %5d / %sn", val,cd[this].name);
  583. }
  584. /* programm the msp3400 according to the results */
  585. msp->main   = carrier_detect_main[max1].cdo;
  586. switch (max1) {
  587. case 1: /* 5.5 */
  588. if (max2 == 0) {
  589. /* B/G FM-stereo */
  590. msp->second = carrier_detect_55[max2].cdo;
  591. msp3400c_setmode(msp, MSP_MODE_FM_TERRA);
  592. msp3400c_setstereo(msp, VIDEO_SOUND_MONO);
  593. msp->watch_stereo = 1;
  594. } else if (max2 == 1 && msp->nicam) {
  595. /* B/G NICAM */
  596. msp->second = carrier_detect_55[max2].cdo;
  597. msp3400c_setmode(msp, MSP_MODE_FM_NICAM1);
  598. msp3400c_setcarrier(msp->bus, msp->second, msp->main);
  599. msp->watch_stereo = 1;
  600. } else {
  601. goto no_second;
  602. }
  603. break;
  604. case 2: /* 6.0 */
  605. /* PAL I NICAM */
  606. msp->second = MSP_CARRIER(6.552);
  607. msp3400c_setmode(msp, MSP_MODE_FM_NICAM2);
  608. msp3400c_setcarrier(msp->bus, msp->second, msp->main);
  609. msp->watch_stereo = 1;
  610. break;
  611. case 3: /* 6.5 */
  612. if (max2 == 1 || max2 == 2) {
  613. /* D/K FM-stereo */
  614. msp->second = carrier_detect_65[max2].cdo;
  615. msp3400c_setmode(msp, MSP_MODE_FM_TERRA);
  616. msp3400c_setstereo(msp, VIDEO_SOUND_MONO);
  617. msp->watch_stereo = 1;
  618. } else if (max2 == 0 && msp->nicam) {
  619. /* D/K NICAM */
  620. msp->second = carrier_detect_65[max2].cdo;
  621. msp3400c_setmode(msp, MSP_MODE_FM_NICAM1);
  622. msp3400c_setcarrier(msp->bus, msp->second, msp->main);
  623. msp->watch_stereo = 1;
  624. } else {
  625. goto no_second;
  626. }
  627. break;
  628. case 0: /* 4.5 */
  629. default:
  630. no_second:
  631. msp->second = carrier_detect_main[max1].cdo;
  632. msp3400c_setmode(msp, MSP_MODE_FM_TERRA);
  633. msp3400c_setcarrier(msp->bus, msp->second, msp->main);
  634. break;
  635. }
  636. /* unmute */
  637. msp3400c_setvolume(msp->bus, msp->left, msp->right);
  638. UNLOCK_I2C_BUS(msp->bus);
  639. if (msp->watch_stereo) {
  640. del_timer(&msp->wake_stereo);
  641. msp->wake_stereo.expires = jiffies + 2*HZ;
  642. add_timer(&msp->wake_stereo);
  643. }
  644. if (debug)
  645. msp3400c_print_mode(msp);
  646. msp->active = 0;
  647. }
  648. done:
  649. dprintk("msp3400: thread: exitn");
  650. msp->active = 0;
  651. msp->thread = NULL;
  652. if(msp->notify != NULL)
  653. up(msp->notify);
  654. return 0;
  655. }
  656. #if 0 /* not finished yet */
  657. static int msp3410d_thread(void *data)
  658. {
  659. unsigned long flags;
  660. struct msp3400c *msp = data;
  661. struct semaphore sem = MUTEX_LOCKED;
  662. int              i, val;
  663. /* lock_kernel(); */
  664.     
  665. exit_mm(current);
  666. current->session = 1;
  667. current->pgrp = 1;
  668. sigfillset(&current->blocked);
  669. current->fs->umask = 0;
  670. strcpy(current->comm,"msp3410 (nicam)");
  671. msp->wait   = &sem;
  672. msp->thread = current;
  673. /* unlock_kernel(); */
  674. dprintk("msp3410: thread: startn");
  675. if(msp->notify != NULL)
  676. up(msp->notify);
  677. for (;;) {
  678. if (msp->rmmod)
  679. goto done;
  680. dprintk("msp3410: thread: sleepn");
  681. down_interruptible(&sem);
  682. dprintk("msp3410: thread: wakeupn");
  683. if (msp->rmmod)
  684. goto done;
  685. if (VIDEO_MODE_RADIO == msp->norm)
  686. continue;  /* nothing to do */
  687. msp->active = 1;
  688. restart:
  689. LOCK_I2C_BUS(msp->bus);
  690. /* mute */
  691. msp3400c_setvolume(msp->bus, 0);
  692. /* quick & dirty hack:
  693.    get the audio proccessor into some useful state */
  694. msp3400c_setmode(msp, MSP_MODE_FM_NICAM1);
  695. /* kick autodetect */
  696. msp3400c_write(msp->bus, I2C_MSP3400C_DFP, 0x20, 0x01);
  697. msp3400c_write(msp->bus, I2C_MSP3400C_DFP, 0x21, 0x01);
  698. UNLOCK_I2C_BUS(msp->bus);
  699. /* wait 1 sec */
  700. current->state = TASK_INTERRUPTIBLE;
  701. current->timeout = jiffies + HZ;
  702. schedule();
  703. if (signal_pending(current))
  704. goto done;
  705. if (msp->restart) {
  706. msp->restart = 0;
  707. goto restart;
  708. }
  709. LOCK_I2C_BUS(msp->bus);
  710. /* debug register dump */
  711. for (i = 0; i < sizeof(d1)/sizeof(struct REGISTER_DUMP); i++) {
  712. val = msp3400c_read(msp->bus,I2C_MSP3400C_DEM,d1[i].addr);
  713. printk(KERN_DEBUG "msp3400: %s = 0x%xn",d1[i].name,val);
  714. }
  715. /* unmute */
  716. msp3400c_setvolume(msp->bus, msp->volume);
  717. UNLOCK_I2C_BUS(msp->bus);
  718. msp->active = 0;
  719. }
  720. done:
  721. dprintk("msp3410: thread: exitn");
  722. msp->wait   = NULL;
  723. msp->active = 0;
  724. msp->thread = NULL;
  725. if(msp->notify != NULL)
  726. up(msp->notify);
  727. return 0;
  728. }
  729. #endif
  730. /* ----------------------------------------------------------------------- */
  731. /* mixer stuff -- with the modular sound driver in 2.1.x we can easily     */
  732. /* register the msp3400 as mixer device                                    */
  733. #ifdef REGISTER_MIXER
  734. #include <linux/sound.h>
  735. #include <linux/soundcard.h>
  736. #include <asm/uaccess.h>
  737. static struct msp3400c *mspmix = NULL;  /* ugly hack, should do something more sensible */
  738. static int mixer_num;
  739. static int mixer_modcnt = 0;
  740. static struct semaphore mixer_sem = MUTEX;
  741. static int mix_to_v4l(int i)
  742. {
  743. int r;
  744. r = ((i & 0xff) * 65536 + 50) / 100;
  745. if (r > 65535) r = 65535;
  746. if (r <     0) r =     0;
  747. return r;
  748. }
  749. static int v4l_to_mix(int i)
  750. {
  751. int r;
  752. r = (i * 100 + 32768) / 65536;
  753. if (r > 100) r = 100;
  754. if (r <   0) r =   0;
  755. return r | (r << 8);
  756. }
  757. static int v4l_to_mix2(int l, int r)
  758. {
  759. r = (r * 100 + 32768) / 65536;
  760. if (r > 100) r = 100;
  761. if (r <   0) r =   0;
  762. l = (l * 100 + 32768) / 65536;
  763. if (l > 100) l = 100;
  764. if (l <   0) l =   0;
  765. return (r << 8) | l;
  766. }
  767. static int
  768. msp3400c_mixer_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
  769. {
  770. int ret,val = 0;
  771. LOCK_FLAGS;
  772.         if (cmd == SOUND_MIXER_INFO) {
  773.                 mixer_info info;
  774.                 strncpy(info.id, "MSP3400", sizeof(info.id));
  775.                 strncpy(info.name, "MSP 3400", sizeof(info.name));
  776.                 info.modify_counter = mixer_modcnt;
  777.                 if (copy_to_user((void *)arg, &info, sizeof(info)))
  778.                         return -EFAULT;
  779.                 return 0;
  780.         }
  781.         if (cmd == SOUND_OLD_MIXER_INFO) {
  782.                 _old_mixer_info info;
  783.                 strncpy(info.id, "MSP3400", sizeof(info.id));
  784.                 strncpy(info.name, "MSP 3400", sizeof(info.name));
  785.                 if (copy_to_user((void *)arg, &info, sizeof(info)))
  786.                         return -EFAULT;
  787.                 return 0;
  788.         }
  789.         if (cmd == OSS_GETVERSION)
  790.                 return put_user(SOUND_VERSION, (int *)arg);
  791. if (_SIOC_DIR(cmd) & _SIOC_WRITE)
  792. if (get_user(val, (int *)arg))
  793. return -EFAULT;
  794.     
  795. down(&mixer_sem);
  796. if (!mspmix) {
  797. up(&mixer_sem);
  798. return -ENODEV;
  799. }
  800. switch (cmd) {
  801. case MIXER_READ(SOUND_MIXER_RECMASK):
  802. case MIXER_READ(SOUND_MIXER_CAPS):
  803. case MIXER_READ(SOUND_MIXER_RECSRC):
  804. case MIXER_WRITE(SOUND_MIXER_RECSRC):
  805. ret = 0;
  806. break;
  807. case MIXER_READ(SOUND_MIXER_STEREODEVS):
  808. ret = SOUND_MASK_VOLUME;
  809. break;
  810. case MIXER_READ(SOUND_MIXER_DEVMASK):
  811. ret = SOUND_MASK_VOLUME | SOUND_MASK_BASS | SOUND_MASK_TREBLE;
  812. break;
  813. case MIXER_WRITE(SOUND_MIXER_VOLUME):
  814. mspmix->left  = mix_to_v4l(val);
  815. mspmix->right = mix_to_v4l(val >> 8);
  816. LOCK_I2C_BUS(mspmix->bus);
  817. msp3400c_setvolume(mspmix->bus,mspmix->left,mspmix->right);
  818. UNLOCK_I2C_BUS(mspmix->bus);
  819. mixer_modcnt++;
  820. /* fall */
  821. case MIXER_READ(SOUND_MIXER_VOLUME):
  822. ret = v4l_to_mix2(mspmix->left, mspmix->right);
  823. break;
  824. case MIXER_WRITE(SOUND_MIXER_BASS):
  825. mspmix->bass = mix_to_v4l(val);
  826. LOCK_I2C_BUS(mspmix->bus);
  827. msp3400c_setbass(mspmix->bus,mspmix->bass);
  828. UNLOCK_I2C_BUS(mspmix->bus);
  829. mixer_modcnt++;
  830. /* fall */
  831. case MIXER_READ(SOUND_MIXER_BASS):
  832. ret = v4l_to_mix(mspmix->bass);
  833. break;
  834. case MIXER_WRITE(SOUND_MIXER_TREBLE):
  835. mspmix->treble = mix_to_v4l(val);
  836. LOCK_I2C_BUS(mspmix->bus);
  837. msp3400c_settreble(mspmix->bus,mspmix->treble);
  838. UNLOCK_I2C_BUS(mspmix->bus);
  839. mixer_modcnt++;
  840. /* fall */
  841. case MIXER_READ(SOUND_MIXER_TREBLE):
  842. ret = v4l_to_mix(mspmix->treble);
  843. break;
  844. default:
  845. up(&mixer_sem);
  846. return -EINVAL;
  847. }
  848. up(&mixer_sem);
  849. if (put_user(ret, (int *)arg))
  850. return -EFAULT;
  851. return 0;
  852. }
  853. static int
  854. msp3400c_mixer_open(struct inode *inode, struct file *file)
  855. {
  856.         MOD_INC_USE_COUNT;
  857.         return 0;
  858. }
  859. static int
  860. msp3400c_mixer_release(struct inode *inode, struct file *file)
  861. {
  862.         MOD_DEC_USE_COUNT;
  863.         return 0;
  864. }
  865. static loff_t
  866. msp3400c_mixer_llseek(struct file *file, loff_t offset, int origin)
  867. {
  868.         return -ESPIPE;
  869. }
  870. static /*const*/ struct file_operations msp3400c_mixer_fops = {
  871.         &msp3400c_mixer_llseek,
  872.         NULL,  /* read */
  873.         NULL,  /* write */
  874.         NULL,  /* readdir */
  875.         NULL,  /* poll */
  876.         &msp3400c_mixer_ioctl,
  877.         NULL,  /* mmap */
  878.         &msp3400c_mixer_open,
  879. NULL,
  880.         &msp3400c_mixer_release,
  881.         NULL,  /* fsync */
  882.         NULL,  /* fasync */
  883.         NULL,  /* check_media_change */
  884.         NULL,  /* revalidate */
  885.         NULL,  /* lock */
  886. };
  887. #endif
  888. /* ----------------------------------------------------------------------- */
  889. static int msp3400c_attach(struct i2c_device *device)
  890. {
  891. struct semaphore sem = MUTEX_LOCKED;
  892. struct msp3400c *msp;
  893. int              rev1,rev2;
  894. LOCK_FLAGS;
  895. device->data = msp = kmalloc(sizeof(struct msp3400c),GFP_KERNEL);
  896. if (NULL == msp)
  897. return -ENOMEM;
  898. memset(msp,0,sizeof(struct msp3400c));
  899. msp->bus = device->bus;
  900. msp->left   = 65535;
  901. msp->right  = 65535;
  902. msp->bass   = 32768;
  903. msp->treble = 32768;
  904. LOCK_I2C_BUS(msp->bus);
  905. if (-1 == msp3400c_reset(msp->bus)) {
  906. UNLOCK_I2C_BUS(msp->bus);
  907. kfree(msp);
  908. dprintk("msp3400: no chip foundn");
  909. return -1;
  910. }
  911.     
  912. rev1 = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1e);
  913. rev2 = msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1f);
  914. if (0 == rev1 && 0 == rev2) {
  915. UNLOCK_I2C_BUS(msp->bus);
  916. kfree(msp);
  917. printk("msp3400: error while reading chip versionn");
  918. return -1;
  919. }
  920. msp3400c_setmode(msp, MSP_MODE_FM_TERRA);
  921. msp3400c_setvolume(msp->bus, msp->left, msp->right);
  922. msp3400c_setbass(msp->bus, msp->bass);
  923. msp3400c_settreble(msp->bus, msp->treble);
  924.     
  925. #if 0
  926. /* this will turn on a 1kHz beep - might be useful for debugging... */
  927. msp3400c_write(msp->bus,I2C_MSP3400C_DFP, 0x0014, 0x1040);
  928. #endif
  929. UNLOCK_I2C_BUS(msp->bus);
  930. sprintf(device->name,"MSP34%02d%c-%c%d",
  931. (rev2>>8)&0xff, (rev1&0xff)+'@', ((rev1>>8)&0xff)+'@', rev2&0x1f);
  932. msp->nicam = (((rev2>>8)&0xff) != 00) ? 1 : 0;
  933. /* timer for stereo checking */
  934. msp->wake_stereo.function = msp3400c_stereo_wake;
  935. msp->wake_stereo.data     = (unsigned long)msp;
  936. /* startup control thread */
  937. MOD_INC_USE_COUNT;
  938. msp->wq     = NULL;
  939. msp->notify = &sem;
  940. kernel_thread(msp3400c_thread, (void *)msp, 0);
  941. down(&sem);
  942. msp->notify = NULL;
  943. wake_up_interruptible(&msp->wq);
  944. printk(KERN_INFO "msp3400: init: chip=%s",device->name);
  945. if (msp->nicam)
  946. printk(", has NICAM support");
  947. #ifdef REGISTER_MIXER
  948. down(&mixer_sem);
  949. mspmix = msp;
  950. up(&mixer_sem);
  951. #endif
  952. printk("n");
  953. return 0;
  954. }
  955. static int msp3400c_detach(struct i2c_device *device)
  956. {
  957. struct semaphore sem = MUTEX_LOCKED;
  958. struct msp3400c *msp  = (struct msp3400c*)device->data;
  959. LOCK_FLAGS;
  960.     
  961. #ifdef REGISTER_MIXER
  962. down(&mixer_sem);
  963. mspmix = NULL;
  964. up(&mixer_sem);
  965. #endif
  966. /* shutdown control thread */
  967. del_timer(&msp->wake_stereo);
  968. if (msp->thread) 
  969. {
  970. msp->notify = &sem;
  971. msp->rmmod = 1;
  972. wake_up_interruptible(&msp->wq);
  973. down(&sem);
  974. msp->notify = NULL;
  975. }
  976.     
  977. LOCK_I2C_BUS(msp->bus);
  978. msp3400c_reset(msp->bus);
  979. UNLOCK_I2C_BUS(msp->bus);
  980. kfree(msp);
  981. MOD_DEC_USE_COUNT;
  982. return 0;
  983. }
  984. static int msp3400c_command(struct i2c_device *device,
  985.  unsigned int cmd, void *arg)
  986. {
  987. struct msp3400c *msp  = (struct msp3400c*)device->data;
  988. int             *iarg = (int*)arg;
  989.         __u16           *sarg = arg;
  990. LOCK_FLAGS;
  991. switch (cmd) {
  992. case MSP_SET_RADIO:
  993. msp->norm = VIDEO_MODE_RADIO;
  994. msp->watch_stereo=0;
  995. del_timer(&msp->wake_stereo);
  996. LOCK_I2C_BUS(msp->bus);
  997. msp3400c_setmode(msp,MSP_MODE_FM_RADIO);
  998. msp3400c_setcarrier(msp->bus, MSP_CARRIER(10.7),MSP_CARRIER(10.7));
  999. msp3400c_setvolume(msp->bus,msp->left, msp->right);
  1000. UNLOCK_I2C_BUS(msp->bus);
  1001. break;
  1002. case MSP_SET_TVNORM:
  1003. msp->norm = *iarg;
  1004. break;
  1005. case MSP_SWITCH_MUTE:
  1006. /* channels switching step one -- mute */
  1007. msp->watch_stereo=0;
  1008. del_timer(&msp->wake_stereo);
  1009. LOCK_I2C_BUS(msp->bus);
  1010. msp3400c_setvolume(msp->bus,0,0);
  1011. UNLOCK_I2C_BUS(msp->bus);
  1012. break;
  1013. case MSP_NEWCHANNEL:
  1014. /* channels switching step two -- trigger sound carrier scan */
  1015. msp->watch_stereo=0;
  1016. del_timer(&msp->wake_stereo);
  1017. if (msp->active)
  1018. msp->restart = 1;
  1019. wake_up_interruptible(&msp->wq);
  1020. break;
  1021. case MSP_GET_VOLUME:
  1022. *sarg = (msp->left > msp->right) ? msp->left : msp->right;
  1023. break;
  1024. case MSP_SET_VOLUME:
  1025. msp->left = msp->right = *sarg;
  1026. LOCK_I2C_BUS(msp->bus);
  1027. msp3400c_setvolume(msp->bus,msp->left, msp->right);
  1028. UNLOCK_I2C_BUS(msp->bus);
  1029. break;
  1030. case MSP_GET_BASS:
  1031. *sarg = msp->bass;
  1032. break;
  1033. case MSP_SET_BASS:
  1034. msp->bass = *sarg;
  1035. LOCK_I2C_BUS(msp->bus);
  1036. msp3400c_setbass(msp->bus,msp->bass);
  1037. UNLOCK_I2C_BUS(msp->bus);
  1038. break;
  1039. case MSP_GET_TREBLE:
  1040. *sarg = msp->treble;
  1041. break;
  1042. case MSP_SET_TREBLE:
  1043. msp->treble = *sarg;
  1044. LOCK_I2C_BUS(msp->bus);
  1045. msp3400c_settreble(msp->bus,msp->treble);
  1046. UNLOCK_I2C_BUS(msp->bus);
  1047. break;
  1048. case MSP_GET_STEREO:
  1049. *sarg = msp->stereo;
  1050. break;
  1051. case MSP_SET_STEREO:
  1052. if (*sarg) {
  1053. msp->watch_stereo=0;
  1054. del_timer(&msp->wake_stereo);
  1055. LOCK_I2C_BUS(msp->bus);
  1056. msp3400c_setstereo(msp,*sarg);
  1057. UNLOCK_I2C_BUS(msp->bus);
  1058. }
  1059. break;
  1060. case MSP_GET_DC:
  1061. LOCK_I2C_BUS(msp->bus);
  1062. *sarg = ((int)msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1b) +
  1063.  (int)msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1c));
  1064. UNLOCK_I2C_BUS(msp->bus);
  1065. break;
  1066.         case MSP_GET_UNIT:
  1067. LOCK_I2C_BUS(msp->bus);
  1068.          *sarg = (int)msp3400c_read(msp->bus, I2C_MSP3400C_DFP, 0x1e);
  1069. UNLOCK_I2C_BUS(msp->bus);
  1070.                 break;
  1071. default:
  1072. return -EINVAL;
  1073. }
  1074. return 0;
  1075. }
  1076. /* ----------------------------------------------------------------------- */
  1077. struct i2c_driver i2c_driver_msp = {
  1078. "msp3400",                    /* name       */
  1079. I2C_DRIVERID_MSP3400,         /* ID         */
  1080. I2C_MSP3400C, I2C_MSP3400C,   /* addr range */
  1081. msp3400c_attach,
  1082. msp3400c_detach,
  1083. msp3400c_command
  1084. };
  1085. #ifdef MODULE
  1086. int init_module(void)
  1087. #else
  1088.      int msp3400c_init(void)
  1089. #endif
  1090. {
  1091. i2c_register_driver(&i2c_driver_msp);
  1092. #ifdef REGISTER_MIXER
  1093. if ((mixer_num = register_sound_mixer(&msp3400c_mixer_fops, -1)) < 0)
  1094. printk(KERN_ERR "msp3400c: cannot allocate mixer devicen");
  1095. #endif
  1096. return 0;
  1097. }
  1098. #ifdef MODULE
  1099. void cleanup_module(void)
  1100. {
  1101. i2c_unregister_driver(&i2c_driver_msp);
  1102. #ifdef REGISTER_MIXER
  1103. if (mixer_num >= 0)
  1104. unregister_sound_mixer(mixer_num);
  1105. #endif
  1106. }
  1107. #endif
  1108. /*
  1109.  * Overrides for Emacs so that we follow Linus's tabbing style.
  1110.  * ---------------------------------------------------------------------------
  1111.  * Local variables:
  1112.  * c-basic-offset: 8
  1113.  * End:
  1114.  */