aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/common
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2009-12-09 22:50:49 -0500
commit3e7468313758913c5e4d372f35b271b96bad1298 (patch)
treeeb612d252a9e2349a1173451cd779beebd18a33e /drivers/media/common
parent6825fbc4cb219f2c98bb7d157915d797cf5cb823 (diff)
parente97f4677961f68e29bd906022ebf60a6df7f530a (diff)
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6
* 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/mchehab/linux-2.6: (345 commits) V4L/DVB (13542): ir-keytable: Allow dynamic table change V4L/DVB (13541): atbm8830: replace 64-bit division and floating point usage V4L/DVB (13540): ir-common: Cleanup get key evdev code V4L/DVB (13539): ir-common: add __func__ for debug messages V4L/DVB (13538): ir-common: Use a dynamic keycode table V4L/DVB (13537): ir: Prepare the code for dynamic keycode table allocation V4L/DVB (13536): em28xx: Use the full RC5 code on HVR-950 Remote Controller V4L/DVB (13535): ir-common: Add a hauppauge new table with the complete RC5 code V4L/DVB (13534): ir-common: Remove some unused fields/structs V4L/DVB (13533): ir: use dynamic tables, instead of static ones V4L/DVB (13532): ir-common: Add infrastructure to use a dynamic keycode table V4L/DVB (13531): ir-common: rename the debug routine to allow exporting it V4L/DVB (13458): go7007: subdev conversion V4L/DVB (13457): s2250: subdev conversion V4L/DVB (13456): s2250: Change module structure V4L/DVB (13528): em28xx: add support for em2800 VC211A card em28xx: don't reduce scale to half size for em2800 em28xx: don't load audio modules when AC97 is mis-detected em28xx: em2800 chips support max width of 640 V4L/DVB (13523): dvb-bt8xx: fix compile warning ... Fix up trivial conflicts due to spelling fixes from the trivial tree in Documentation/video4linux/gspca.txt drivers/media/video/cx18/cx18-mailbox.h
Diffstat (limited to 'drivers/media/common')
-rw-r--r--drivers/media/common/Makefile2
-rw-r--r--drivers/media/common/ir-functions.c71
-rw-r--r--drivers/media/common/ir-keymaps.c167
-rw-r--r--drivers/media/common/ir-keytable.c429
-rw-r--r--drivers/media/common/saa7146_video.c16
-rw-r--r--drivers/media/common/tuners/Kconfig7
-rw-r--r--drivers/media/common/tuners/Makefile1
-rw-r--r--drivers/media/common/tuners/max2165.c442
-rw-r--r--drivers/media/common/tuners/max2165.h48
-rw-r--r--drivers/media/common/tuners/max2165_priv.h60
-rw-r--r--drivers/media/common/tuners/mxl5005s.c5
-rw-r--r--drivers/media/common/tuners/mxl5005s.h4
-rw-r--r--drivers/media/common/tuners/mxl5007t.c2
-rw-r--r--drivers/media/common/tuners/tda18271-common.c16
-rw-r--r--drivers/media/common/tuners/tda18271-fe.c114
-rw-r--r--drivers/media/common/tuners/tda18271-maps.c1
-rw-r--r--drivers/media/common/tuners/tda18271-priv.h47
-rw-r--r--drivers/media/common/tuners/tda18271.h12
-rw-r--r--drivers/media/common/tuners/tda8290.c1
-rw-r--r--drivers/media/common/tuners/tda9887.c2
-rw-r--r--drivers/media/common/tuners/xc5000.c97
-rw-r--r--drivers/media/common/tuners/xc5000.h6
22 files changed, 1431 insertions, 119 deletions
diff --git a/drivers/media/common/Makefile b/drivers/media/common/Makefile
index 351b98b9b302..169b337b7c9d 100644
--- a/drivers/media/common/Makefile
+++ b/drivers/media/common/Makefile
@@ -1,6 +1,6 @@
1saa7146-objs := saa7146_i2c.o saa7146_core.o 1saa7146-objs := saa7146_i2c.o saa7146_core.o
2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o 2saa7146_vv-objs := saa7146_fops.o saa7146_video.o saa7146_hlp.o saa7146_vbi.o
3ir-common-objs := ir-functions.o ir-keymaps.o 3ir-common-objs := ir-functions.o ir-keymaps.o ir-keytable.o
4 4
5obj-y += tuners/ 5obj-y += tuners/
6obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o 6obj-$(CONFIG_VIDEO_SAA7146) += saa7146.o
diff --git a/drivers/media/common/ir-functions.c b/drivers/media/common/ir-functions.c
index abd4791acb0e..e616f624ceaa 100644
--- a/drivers/media/common/ir-functions.c
+++ b/drivers/media/common/ir-functions.c
@@ -34,22 +34,19 @@ static int repeat = 1;
34module_param(repeat, int, 0444); 34module_param(repeat, int, 0444);
35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)"); 35MODULE_PARM_DESC(repeat,"auto-repeat for IR keys (default: on)");
36 36
37static int debug; /* debug level (0,1,2) */ 37int media_ir_debug; /* media_ir_debug level (0,1,2) */
38module_param(debug, int, 0644); 38module_param_named(debug, media_ir_debug, int, 0644);
39
40#define dprintk(level, fmt, arg...) if (debug >= level) \
41 printk(KERN_DEBUG fmt , ## arg)
42 39
43/* -------------------------------------------------------------------------- */ 40/* -------------------------------------------------------------------------- */
44 41
45static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir) 42static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
46{ 43{
47 if (KEY_RESERVED == ir->keycode) { 44 if (KEY_RESERVED == ir->keycode) {
48 printk(KERN_INFO "%s: unknown key: key=0x%02x raw=0x%02x down=%d\n", 45 printk(KERN_INFO "%s: unknown key: key=0x%02x down=%d\n",
49 dev->name,ir->ir_key,ir->ir_raw,ir->keypressed); 46 dev->name, ir->ir_key, ir->keypressed);
50 return; 47 return;
51 } 48 }
52 dprintk(1,"%s: key event code=%d down=%d\n", 49 IR_dprintk(1,"%s: key event code=%d down=%d\n",
53 dev->name,ir->keycode,ir->keypressed); 50 dev->name,ir->keycode,ir->keypressed);
54 input_report_key(dev,ir->keycode,ir->keypressed); 51 input_report_key(dev,ir->keycode,ir->keypressed);
55 input_sync(dev); 52 input_sync(dev);
@@ -57,39 +54,34 @@ static void ir_input_key_event(struct input_dev *dev, struct ir_input_state *ir)
57 54
58/* -------------------------------------------------------------------------- */ 55/* -------------------------------------------------------------------------- */
59 56
60void ir_input_init(struct input_dev *dev, struct ir_input_state *ir, 57int ir_input_init(struct input_dev *dev, struct ir_input_state *ir,
61 int ir_type, struct ir_scancode_table *ir_codes) 58 int ir_type, struct ir_scancode_table *ir_codes)
62{ 59{
63 int i;
64
65 ir->ir_type = ir_type; 60 ir->ir_type = ir_type;
66 61
67 memset(ir->ir_codes, 0, sizeof(ir->ir_codes)); 62 ir->keytable.size = ir_roundup_tablesize(ir_codes->size);
63 ir->keytable.scan = kzalloc(ir->keytable.size *
64 sizeof(struct ir_scancode), GFP_KERNEL);
65 if (!ir->keytable.scan)
66 return -ENOMEM;
68 67
69 /* 68 IR_dprintk(1, "Allocated space for %d keycode entries (%zd bytes)\n",
70 * FIXME: This is a temporary workaround to use the new IR tables 69 ir->keytable.size,
71 * with the old approach. Later patches will replace this to a 70 ir->keytable.size * sizeof(ir->keytable.scan));
72 * proper method
73 */
74 71
75 if (ir_codes) 72 ir_copy_table(&ir->keytable, ir_codes);
76 for (i = 0; i < ir_codes->size; i++) 73 ir_set_keycode_table(dev, &ir->keytable);
77 if (ir_codes->scan[i].scancode < IR_KEYTAB_SIZE)
78 ir->ir_codes[ir_codes->scan[i].scancode] = ir_codes->scan[i].keycode;
79 74
80 dev->keycode = ir->ir_codes;
81 dev->keycodesize = sizeof(IR_KEYTAB_TYPE);
82 dev->keycodemax = IR_KEYTAB_SIZE;
83 for (i = 0; i < IR_KEYTAB_SIZE; i++)
84 set_bit(ir->ir_codes[i], dev->keybit);
85 clear_bit(0, dev->keybit); 75 clear_bit(0, dev->keybit);
86
87 set_bit(EV_KEY, dev->evbit); 76 set_bit(EV_KEY, dev->evbit);
88 if (repeat) 77 if (repeat)
89 set_bit(EV_REP, dev->evbit); 78 set_bit(EV_REP, dev->evbit);
79
80 return 0;
90} 81}
91EXPORT_SYMBOL_GPL(ir_input_init); 82EXPORT_SYMBOL_GPL(ir_input_init);
92 83
84
93void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir) 85void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
94{ 86{
95 if (ir->keypressed) { 87 if (ir->keypressed) {
@@ -100,9 +92,9 @@ void ir_input_nokey(struct input_dev *dev, struct ir_input_state *ir)
100EXPORT_SYMBOL_GPL(ir_input_nokey); 92EXPORT_SYMBOL_GPL(ir_input_nokey);
101 93
102void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir, 94void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
103 u32 ir_key, u32 ir_raw) 95 u32 ir_key)
104{ 96{
105 u32 keycode = IR_KEYCODE(ir->ir_codes, ir_key); 97 u32 keycode = ir_g_keycode_from_table(dev, ir_key);
106 98
107 if (ir->keypressed && ir->keycode != keycode) { 99 if (ir->keypressed && ir->keycode != keycode) {
108 ir->keypressed = 0; 100 ir->keypressed = 0;
@@ -110,7 +102,6 @@ void ir_input_keydown(struct input_dev *dev, struct ir_input_state *ir,
110 } 102 }
111 if (!ir->keypressed) { 103 if (!ir->keypressed) {
112 ir->ir_key = ir_key; 104 ir->ir_key = ir_key;
113 ir->ir_raw = ir_raw;
114 ir->keycode = keycode; 105 ir->keycode = keycode;
115 ir->keypressed = 1; 106 ir->keypressed = 1;
116 ir_input_key_event(dev,ir); 107 ir_input_key_event(dev,ir);
@@ -275,7 +266,7 @@ EXPORT_SYMBOL_GPL(ir_decode_biphase);
275 * saa7134 */ 266 * saa7134 */
276 267
277/* decode raw bit pattern to RC5 code */ 268/* decode raw bit pattern to RC5 code */
278static u32 ir_rc5_decode(unsigned int code) 269u32 ir_rc5_decode(unsigned int code)
279{ 270{
280 unsigned int org_code = code; 271 unsigned int org_code = code;
281 unsigned int pair; 272 unsigned int pair;
@@ -295,15 +286,16 @@ static u32 ir_rc5_decode(unsigned int code)
295 rc5 |= 1; 286 rc5 |= 1;
296 break; 287 break;
297 case 3: 288 case 3:
298 dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code); 289 IR_dprintk(1, "ir-common: ir_rc5_decode(%x) bad code\n", org_code);
299 return 0; 290 return 0;
300 } 291 }
301 } 292 }
302 dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, " 293 IR_dprintk(1, "ir-common: code=%x, rc5=%x, start=%x, toggle=%x, address=%x, "
303 "instr=%x\n", rc5, org_code, RC5_START(rc5), 294 "instr=%x\n", rc5, org_code, RC5_START(rc5),
304 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5)); 295 RC5_TOGGLE(rc5), RC5_ADDR(rc5), RC5_INSTR(rc5));
305 return rc5; 296 return rc5;
306} 297}
298EXPORT_SYMBOL_GPL(ir_rc5_decode);
307 299
308void ir_rc5_timer_end(unsigned long data) 300void ir_rc5_timer_end(unsigned long data)
309{ 301{
@@ -330,20 +322,20 @@ void ir_rc5_timer_end(unsigned long data)
330 322
331 /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */ 323 /* Allow some timer jitter (RC5 is ~24ms anyway so this is ok) */
332 if (gap < 28000) { 324 if (gap < 28000) {
333 dprintk(1, "ir-common: spurious timer_end\n"); 325 IR_dprintk(1, "ir-common: spurious timer_end\n");
334 return; 326 return;
335 } 327 }
336 328
337 if (ir->last_bit < 20) { 329 if (ir->last_bit < 20) {
338 /* ignore spurious codes (caused by light/other remotes) */ 330 /* ignore spurious codes (caused by light/other remotes) */
339 dprintk(1, "ir-common: short code: %x\n", ir->code); 331 IR_dprintk(1, "ir-common: short code: %x\n", ir->code);
340 } else { 332 } else {
341 ir->code = (ir->code << ir->shift_by) | 1; 333 ir->code = (ir->code << ir->shift_by) | 1;
342 rc5 = ir_rc5_decode(ir->code); 334 rc5 = ir_rc5_decode(ir->code);
343 335
344 /* two start bits? */ 336 /* two start bits? */
345 if (RC5_START(rc5) != ir->start) { 337 if (RC5_START(rc5) != ir->start) {
346 dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5)); 338 IR_dprintk(1, "ir-common: rc5 start bits invalid: %u\n", RC5_START(rc5));
347 339
348 /* right address? */ 340 /* right address? */
349 } else if (RC5_ADDR(rc5) == ir->addr) { 341 } else if (RC5_ADDR(rc5) == ir->addr) {
@@ -353,11 +345,10 @@ void ir_rc5_timer_end(unsigned long data)
353 /* Good code, decide if repeat/repress */ 345 /* Good code, decide if repeat/repress */
354 if (toggle != RC5_TOGGLE(ir->last_rc5) || 346 if (toggle != RC5_TOGGLE(ir->last_rc5) ||
355 instr != RC5_INSTR(ir->last_rc5)) { 347 instr != RC5_INSTR(ir->last_rc5)) {
356 dprintk(1, "ir-common: instruction %x, toggle %x\n", instr, 348 IR_dprintk(1, "ir-common: instruction %x, toggle %x\n", instr,
357 toggle); 349 toggle);
358 ir_input_nokey(ir->dev, &ir->ir); 350 ir_input_nokey(ir->dev, &ir->ir);
359 ir_input_keydown(ir->dev, &ir->ir, instr, 351 ir_input_keydown(ir->dev, &ir->ir, instr);
360 instr);
361 } 352 }
362 353
363 /* Set/reset key-up timer */ 354 /* Set/reset key-up timer */
@@ -376,7 +367,7 @@ void ir_rc5_timer_keyup(unsigned long data)
376{ 367{
377 struct card_ir *ir = (struct card_ir *)data; 368 struct card_ir *ir = (struct card_ir *)data;
378 369
379 dprintk(1, "ir-common: key released\n"); 370 IR_dprintk(1, "ir-common: key released\n");
380 ir_input_nokey(ir->dev, &ir->ir); 371 ir_input_nokey(ir->dev, &ir->ir);
381} 372}
382EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup); 373EXPORT_SYMBOL_GPL(ir_rc5_timer_keyup);
diff --git a/drivers/media/common/ir-keymaps.c b/drivers/media/common/ir-keymaps.c
index f6790172736a..328c973a0838 100644
--- a/drivers/media/common/ir-keymaps.c
+++ b/drivers/media/common/ir-keymaps.c
@@ -1705,6 +1705,7 @@ static struct ir_scancode ir_codes_winfast[] = {
1705 { 0x37, KEY_RADIO }, /* FM */ 1705 { 0x37, KEY_RADIO }, /* FM */
1706 { 0x38, KEY_DVD }, 1706 { 0x38, KEY_DVD },
1707 1707
1708 { 0x1a, KEY_MODE}, /* change to MCE mode on Y04G0051 */
1708 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */ 1709 { 0x3e, KEY_F21 }, /* MCE +VOL, on Y04G0033 */
1709 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */ 1710 { 0x3a, KEY_F22 }, /* MCE -VOL, on Y04G0033 */
1710 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */ 1711 { 0x3b, KEY_F23 }, /* MCE +CH, on Y04G0033 */
@@ -1846,6 +1847,76 @@ struct ir_scancode_table ir_codes_hauppauge_new_table = {
1846}; 1847};
1847EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table); 1848EXPORT_SYMBOL_GPL(ir_codes_hauppauge_new_table);
1848 1849
1850/*
1851 * Hauppauge:the newer, gray remotes (seems there are multiple
1852 * slightly different versions), shipped with cx88+ivtv cards.
1853 *
1854 * This table contains the complete RC5 code, instead of just the data part
1855 */
1856static struct ir_scancode ir_codes_rc5_hauppauge_new[] = {
1857 /* Keys 0 to 9 */
1858 { 0x1e00, KEY_0 },
1859 { 0x1e01, KEY_1 },
1860 { 0x1e02, KEY_2 },
1861 { 0x1e03, KEY_3 },
1862 { 0x1e04, KEY_4 },
1863 { 0x1e05, KEY_5 },
1864 { 0x1e06, KEY_6 },
1865 { 0x1e07, KEY_7 },
1866 { 0x1e08, KEY_8 },
1867 { 0x1e09, KEY_9 },
1868
1869 { 0x1e0a, KEY_TEXT }, /* keypad asterisk as well */
1870 { 0x1e0b, KEY_RED }, /* red button */
1871 { 0x1e0c, KEY_RADIO },
1872 { 0x1e0d, KEY_MENU },
1873 { 0x1e0e, KEY_SUBTITLE }, /* also the # key */
1874 { 0x1e0f, KEY_MUTE },
1875 { 0x1e10, KEY_VOLUMEUP },
1876 { 0x1e11, KEY_VOLUMEDOWN },
1877 { 0x1e12, KEY_PREVIOUS }, /* previous channel */
1878 { 0x1e14, KEY_UP },
1879 { 0x1e15, KEY_DOWN },
1880 { 0x1e16, KEY_LEFT },
1881 { 0x1e17, KEY_RIGHT },
1882 { 0x1e18, KEY_VIDEO }, /* Videos */
1883 { 0x1e19, KEY_AUDIO }, /* Music */
1884 /* 0x1e1a: Pictures - presume this means
1885 "Multimedia Home Platform" -
1886 no "PICTURES" key in input.h
1887 */
1888 { 0x1e1a, KEY_MHP },
1889
1890 { 0x1e1b, KEY_EPG }, /* Guide */
1891 { 0x1e1c, KEY_TV },
1892 { 0x1e1e, KEY_NEXTSONG }, /* skip >| */
1893 { 0x1e1f, KEY_EXIT }, /* back/exit */
1894 { 0x1e20, KEY_CHANNELUP }, /* channel / program + */
1895 { 0x1e21, KEY_CHANNELDOWN }, /* channel / program - */
1896 { 0x1e22, KEY_CHANNEL }, /* source (old black remote) */
1897 { 0x1e24, KEY_PREVIOUSSONG }, /* replay |< */
1898 { 0x1e25, KEY_ENTER }, /* OK */
1899 { 0x1e26, KEY_SLEEP }, /* minimize (old black remote) */
1900 { 0x1e29, KEY_BLUE }, /* blue key */
1901 { 0x1e2e, KEY_GREEN }, /* green button */
1902 { 0x1e30, KEY_PAUSE }, /* pause */
1903 { 0x1e32, KEY_REWIND }, /* backward << */
1904 { 0x1e34, KEY_FASTFORWARD }, /* forward >> */
1905 { 0x1e35, KEY_PLAY },
1906 { 0x1e36, KEY_STOP },
1907 { 0x1e37, KEY_RECORD }, /* recording */
1908 { 0x1e38, KEY_YELLOW }, /* yellow key */
1909 { 0x1e3b, KEY_SELECT }, /* top right button */
1910 { 0x1e3c, KEY_ZOOM }, /* full */
1911 { 0x1e3d, KEY_POWER }, /* system power (green button) */
1912};
1913
1914struct ir_scancode_table ir_codes_rc5_hauppauge_new_table = {
1915 .scan = ir_codes_rc5_hauppauge_new,
1916 .size = ARRAY_SIZE(ir_codes_rc5_hauppauge_new),
1917};
1918EXPORT_SYMBOL_GPL(ir_codes_rc5_hauppauge_new_table);
1919
1849static struct ir_scancode ir_codes_npgtech[] = { 1920static struct ir_scancode ir_codes_npgtech[] = {
1850 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */ 1921 { 0x1d, KEY_SWITCHVIDEOMODE }, /* switch inputs */
1851 { 0x2a, KEY_FRONT }, 1922 { 0x2a, KEY_FRONT },
@@ -2964,6 +3035,101 @@ struct ir_scancode_table ir_codes_dm1105_nec_table = {
2964}; 3035};
2965EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table); 3036EXPORT_SYMBOL_GPL(ir_codes_dm1105_nec_table);
2966 3037
3038static struct ir_scancode ir_codes_tevii_nec[] = {
3039 { 0x0a, KEY_POWER2},
3040 { 0x0c, KEY_MUTE},
3041 { 0x11, KEY_1},
3042 { 0x12, KEY_2},
3043 { 0x13, KEY_3},
3044 { 0x14, KEY_4},
3045 { 0x15, KEY_5},
3046 { 0x16, KEY_6},
3047 { 0x17, KEY_7},
3048 { 0x18, KEY_8},
3049 { 0x19, KEY_9},
3050 { 0x10, KEY_0},
3051 { 0x1c, KEY_MENU},
3052 { 0x0f, KEY_VOLUMEDOWN},
3053 { 0x1a, KEY_LAST},
3054 { 0x0e, KEY_OPEN},
3055 { 0x04, KEY_RECORD},
3056 { 0x09, KEY_VOLUMEUP},
3057 { 0x08, KEY_CHANNELUP},
3058 { 0x07, KEY_PVR},
3059 { 0x0b, KEY_TIME},
3060 { 0x02, KEY_RIGHT},
3061 { 0x03, KEY_LEFT},
3062 { 0x00, KEY_UP},
3063 { 0x1f, KEY_OK},
3064 { 0x01, KEY_DOWN},
3065 { 0x05, KEY_TUNER},
3066 { 0x06, KEY_CHANNELDOWN},
3067 { 0x40, KEY_PLAYPAUSE},
3068 { 0x1e, KEY_REWIND},
3069 { 0x1b, KEY_FAVORITES},
3070 { 0x1d, KEY_BACK},
3071 { 0x4d, KEY_FASTFORWARD},
3072 { 0x44, KEY_EPG},
3073 { 0x4c, KEY_INFO},
3074 { 0x41, KEY_AB},
3075 { 0x43, KEY_AUDIO},
3076 { 0x45, KEY_SUBTITLE},
3077 { 0x4a, KEY_LIST},
3078 { 0x46, KEY_F1},
3079 { 0x47, KEY_F2},
3080 { 0x5e, KEY_F3},
3081 { 0x5c, KEY_F4},
3082 { 0x52, KEY_F5},
3083 { 0x5a, KEY_F6},
3084 { 0x56, KEY_MODE},
3085 { 0x58, KEY_SWITCHVIDEOMODE},
3086};
3087struct ir_scancode_table ir_codes_tevii_nec_table = {
3088 .scan = ir_codes_tevii_nec,
3089 .size = ARRAY_SIZE(ir_codes_tevii_nec),
3090};
3091EXPORT_SYMBOL_GPL(ir_codes_tevii_nec_table);
3092
3093static struct ir_scancode ir_codes_tbs_nec[] = {
3094 { 0x04, KEY_POWER2}, /*power*/
3095 { 0x14, KEY_MUTE}, /*mute*/
3096 { 0x07, KEY_1},
3097 { 0x06, KEY_2},
3098 { 0x05, KEY_3},
3099 { 0x0b, KEY_4},
3100 { 0x0a, KEY_5},
3101 { 0x09, KEY_6},
3102 { 0x0f, KEY_7},
3103 { 0x0e, KEY_8},
3104 { 0x0d, KEY_9},
3105 { 0x12, KEY_0},
3106 { 0x16, KEY_CHANNELUP}, /*ch+*/
3107 { 0x11, KEY_CHANNELDOWN},/*ch-*/
3108 { 0x13, KEY_VOLUMEUP}, /*vol+*/
3109 { 0x0c, KEY_VOLUMEDOWN},/*vol-*/
3110 { 0x03, KEY_RECORD}, /*rec*/
3111 { 0x18, KEY_PAUSE}, /*pause*/
3112 { 0x19, KEY_OK}, /*ok*/
3113 { 0x1a, KEY_CAMERA}, /* snapshot */
3114 { 0x01, KEY_UP},
3115 { 0x10, KEY_LEFT},
3116 { 0x02, KEY_RIGHT},
3117 { 0x08, KEY_DOWN},
3118 { 0x15, KEY_FAVORITES},
3119 { 0x17, KEY_SUBTITLE},
3120 { 0x1d, KEY_ZOOM},
3121 { 0x1f, KEY_EXIT},
3122 { 0x1e, KEY_MENU},
3123 { 0x1c, KEY_EPG},
3124 { 0x00, KEY_PREVIOUS},
3125 { 0x1b, KEY_MODE},
3126};
3127struct ir_scancode_table ir_codes_tbs_nec_table = {
3128 .scan = ir_codes_tbs_nec,
3129 .size = ARRAY_SIZE(ir_codes_tbs_nec),
3130};
3131EXPORT_SYMBOL_GPL(ir_codes_tbs_nec_table);
3132
2967/* Terratec Cinergy Hybrid T USB XS 3133/* Terratec Cinergy Hybrid T USB XS
2968 Devin Heitmueller <dheitmueller@linuxtv.org> 3134 Devin Heitmueller <dheitmueller@linuxtv.org>
2969 */ 3135 */
@@ -3147,3 +3313,4 @@ struct ir_scancode_table ir_codes_gadmei_rm008z_table = {
3147 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z), 3313 .size = ARRAY_SIZE(ir_codes_gadmei_rm008z),
3148}; 3314};
3149EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table); 3315EXPORT_SYMBOL_GPL(ir_codes_gadmei_rm008z_table);
3316
diff --git a/drivers/media/common/ir-keytable.c b/drivers/media/common/ir-keytable.c
new file mode 100644
index 000000000000..26ce5bc2fdd5
--- /dev/null
+++ b/drivers/media/common/ir-keytable.c
@@ -0,0 +1,429 @@
1/* ir-register.c - handle IR scancode->keycode tables
2 *
3 * Copyright (C) 2009 by Mauro Carvalho Chehab <mchehab@redhat.com>
4 */
5
6#include <linux/usb/input.h>
7
8#include <media/ir-common.h>
9
10#define IR_TAB_MIN_SIZE 32
11#define IR_TAB_MAX_SIZE 1024
12
13/**
14 * ir_seek_table() - returns the element order on the table
15 * @rc_tab: the ir_scancode_table with the keymap to be used
16 * @scancode: the scancode that we're seeking
17 *
18 * This routine is used by the input routines when a key is pressed at the
19 * IR. The scancode is received and needs to be converted into a keycode.
20 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
21 * corresponding keycode from the table.
22 */
23static int ir_seek_table(struct ir_scancode_table *rc_tab, u32 scancode)
24{
25 int rc;
26 unsigned long flags;
27 struct ir_scancode *keymap = rc_tab->scan;
28
29 spin_lock_irqsave(&rc_tab->lock, flags);
30
31 /* FIXME: replace it by a binary search */
32
33 for (rc = 0; rc < rc_tab->size; rc++)
34 if (keymap[rc].scancode == scancode)
35 goto exit;
36
37 /* Not found */
38 rc = -EINVAL;
39
40exit:
41 spin_unlock_irqrestore(&rc_tab->lock, flags);
42 return rc;
43}
44
45/**
46 * ir_roundup_tablesize() - gets an optimum value for the table size
47 * @n_elems: minimum number of entries to store keycodes
48 *
49 * This routine is used to choose the keycode table size.
50 *
51 * In order to have some empty space for new keycodes,
52 * and knowing in advance that kmalloc allocates only power of two
53 * segments, it optimizes the allocated space to have some spare space
54 * for those new keycodes by using the maximum number of entries that
55 * will be effectively be allocated by kmalloc.
56 * In order to reduce the quantity of table resizes, it has a minimum
57 * table size of IR_TAB_MIN_SIZE.
58 */
59int ir_roundup_tablesize(int n_elems)
60{
61 size_t size;
62
63 if (n_elems < IR_TAB_MIN_SIZE)
64 n_elems = IR_TAB_MIN_SIZE;
65
66 /*
67 * As kmalloc only allocates sizes of power of two, get as
68 * much entries as possible for the allocated memory segment
69 */
70 size = roundup_pow_of_two(n_elems * sizeof(struct ir_scancode));
71 n_elems = size / sizeof(struct ir_scancode);
72
73 return n_elems;
74}
75
76/**
77 * ir_copy_table() - copies a keytable, discarding the unused entries
78 * @destin: destin table
79 * @origin: origin table
80 *
81 * Copies all entries where the keycode is not KEY_UNKNOWN/KEY_RESERVED
82 */
83
84int ir_copy_table(struct ir_scancode_table *destin,
85 const struct ir_scancode_table *origin)
86{
87 int i, j = 0;
88
89 for (i = 0; i < origin->size; i++) {
90 if (origin->scan[i].keycode == KEY_UNKNOWN ||
91 origin->scan[i].keycode == KEY_RESERVED)
92 continue;
93
94 memcpy(&destin->scan[j], &origin->scan[i], sizeof(struct ir_scancode));
95 j++;
96 }
97 destin->size = j;
98
99 IR_dprintk(1, "Copied %d scancodes to the new keycode table\n", destin->size);
100
101 return 0;
102}
103
104/**
105 * ir_getkeycode() - get a keycode at the evdev scancode ->keycode table
106 * @dev: the struct input_dev device descriptor
107 * @scancode: the desired scancode
108 * @keycode: the keycode to be retorned.
109 *
110 * This routine is used to handle evdev EVIOCGKEY ioctl.
111 * If the key is not found, returns -EINVAL, otherwise, returns 0.
112 */
113static int ir_getkeycode(struct input_dev *dev,
114 int scancode, int *keycode)
115{
116 int elem;
117 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
118
119 elem = ir_seek_table(rc_tab, scancode);
120 if (elem >= 0) {
121 *keycode = rc_tab->scan[elem].keycode;
122 return 0;
123 }
124
125 /*
126 * Scancode not found and table can't be expanded
127 */
128 if (elem < 0 && rc_tab->size == IR_TAB_MAX_SIZE)
129 return -EINVAL;
130
131 /*
132 * If is there extra space, returns KEY_RESERVED,
133 * otherwise, input core won't let ir_setkeycode to work
134 */
135 *keycode = KEY_RESERVED;
136 return 0;
137}
138
139
140/**
141 * ir_is_resize_needed() - Check if the table needs rezise
142 * @table: keycode table that may need to resize
143 * @n_elems: minimum number of entries to store keycodes
144 *
145 * Considering that kmalloc uses power of two storage areas, this
146 * routine detects if the real alloced size will change. If not, it
147 * just returns without doing nothing. Otherwise, it will extend or
148 * reduce the table size to meet the new needs.
149 *
150 * It returns 0 if no resize is needed, 1 otherwise.
151 */
152static int ir_is_resize_needed(struct ir_scancode_table *table, int n_elems)
153{
154 int cur_size = ir_roundup_tablesize(table->size);
155 int new_size = ir_roundup_tablesize(n_elems);
156
157 if (cur_size == new_size)
158 return 0;
159
160 /* Resize is needed */
161 return 1;
162}
163
164/**
165 * ir_delete_key() - remove a keycode from the table
166 * @rc_tab: keycode table
167 * @elem: element to be removed
168 *
169 */
170static void ir_delete_key(struct ir_scancode_table *rc_tab, int elem)
171{
172 unsigned long flags = 0;
173 int newsize = rc_tab->size - 1;
174 int resize = ir_is_resize_needed(rc_tab, newsize);
175 struct ir_scancode *oldkeymap = rc_tab->scan;
176 struct ir_scancode *newkeymap;
177
178 if (resize) {
179 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
180 sizeof(*newkeymap), GFP_ATOMIC);
181
182 /* There's no memory for resize. Keep the old table */
183 if (!newkeymap)
184 resize = 0;
185 }
186
187 if (!resize) {
188 newkeymap = oldkeymap;
189
190 /* We'll modify the live table. Lock it */
191 spin_lock_irqsave(&rc_tab->lock, flags);
192 }
193
194 /*
195 * Copy the elements before the one that will be deleted
196 * if (!resize), both oldkeymap and newkeymap points
197 * to the same place, so, there's no need to copy
198 */
199 if (resize && elem > 0)
200 memcpy(newkeymap, oldkeymap,
201 elem * sizeof(*newkeymap));
202
203 /*
204 * Copy the other elements overwriting the element to be removed
205 * This operation applies to both resize and non-resize case
206 */
207 if (elem < newsize)
208 memcpy(&newkeymap[elem], &oldkeymap[elem + 1],
209 (newsize - elem) * sizeof(*newkeymap));
210
211 if (resize) {
212 /*
213 * As the copy happened to a temporary table, only here
214 * it needs to lock while replacing the table pointers
215 * to use the new table
216 */
217 spin_lock_irqsave(&rc_tab->lock, flags);
218 rc_tab->size = newsize;
219 rc_tab->scan = newkeymap;
220 spin_unlock_irqrestore(&rc_tab->lock, flags);
221
222 /* Frees the old keytable */
223 kfree(oldkeymap);
224 } else {
225 rc_tab->size = newsize;
226 spin_unlock_irqrestore(&rc_tab->lock, flags);
227 }
228}
229
230/**
231 * ir_insert_key() - insert a keycode at the table
232 * @rc_tab: keycode table
233 * @scancode: the desired scancode
234 * @keycode: the keycode to be retorned.
235 *
236 */
237static int ir_insert_key(struct ir_scancode_table *rc_tab,
238 int scancode, int keycode)
239{
240 unsigned long flags;
241 int elem = rc_tab->size;
242 int newsize = rc_tab->size + 1;
243 int resize = ir_is_resize_needed(rc_tab, newsize);
244 struct ir_scancode *oldkeymap = rc_tab->scan;
245 struct ir_scancode *newkeymap;
246
247 if (resize) {
248 newkeymap = kzalloc(ir_roundup_tablesize(newsize) *
249 sizeof(*newkeymap), GFP_ATOMIC);
250 if (!newkeymap)
251 return -ENOMEM;
252
253 memcpy(newkeymap, oldkeymap,
254 rc_tab->size * sizeof(*newkeymap));
255 } else
256 newkeymap = oldkeymap;
257
258 /* Stores the new code at the table */
259 IR_dprintk(1, "#%d: New scan 0x%04x with key 0x%04x\n",
260 rc_tab->size, scancode, keycode);
261
262 spin_lock_irqsave(&rc_tab->lock, flags);
263 rc_tab->size = newsize;
264 if (resize) {
265 rc_tab->scan = newkeymap;
266 kfree(oldkeymap);
267 }
268 newkeymap[elem].scancode = scancode;
269 newkeymap[elem].keycode = keycode;
270 spin_unlock_irqrestore(&rc_tab->lock, flags);
271
272 return 0;
273}
274
275/**
276 * ir_setkeycode() - set a keycode at the evdev scancode ->keycode table
277 * @dev: the struct input_dev device descriptor
278 * @scancode: the desired scancode
279 * @keycode: the keycode to be retorned.
280 *
281 * This routine is used to handle evdev EVIOCSKEY ioctl.
282 * There's one caveat here: how can we increase the size of the table?
283 * If the key is not found, returns -EINVAL, otherwise, returns 0.
284 */
285static int ir_setkeycode(struct input_dev *dev,
286 int scancode, int keycode)
287{
288 int rc = 0;
289 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
290 struct ir_scancode *keymap = rc_tab->scan;
291 unsigned long flags;
292
293 /*
294 * Handle keycode table deletions
295 *
296 * If userspace is adding a KEY_UNKNOWN or KEY_RESERVED,
297 * deal as a trial to remove an existing scancode attribution
298 * if table become too big, reduce it to save space
299 */
300 if (keycode == KEY_UNKNOWN || keycode == KEY_RESERVED) {
301 rc = ir_seek_table(rc_tab, scancode);
302 if (rc < 0)
303 return 0;
304
305 IR_dprintk(1, "#%d: Deleting scan 0x%04x\n", rc, scancode);
306 clear_bit(keymap[rc].keycode, dev->keybit);
307 ir_delete_key(rc_tab, rc);
308
309 return 0;
310 }
311
312 /*
313 * Handle keycode replacements
314 *
315 * If the scancode exists, just replace by the new value
316 */
317 rc = ir_seek_table(rc_tab, scancode);
318 if (rc >= 0) {
319 IR_dprintk(1, "#%d: Replacing scan 0x%04x with key 0x%04x\n",
320 rc, scancode, keycode);
321
322 clear_bit(keymap[rc].keycode, dev->keybit);
323
324 spin_lock_irqsave(&rc_tab->lock, flags);
325 keymap[rc].keycode = keycode;
326 spin_unlock_irqrestore(&rc_tab->lock, flags);
327
328 set_bit(keycode, dev->keybit);
329
330 return 0;
331 }
332
333 /*
334 * Handle new scancode inserts
335 *
336 * reallocate table if needed and insert a new keycode
337 */
338
339 /* Avoid growing the table indefinitely */
340 if (rc_tab->size + 1 > IR_TAB_MAX_SIZE)
341 return -EINVAL;
342
343 rc = ir_insert_key(rc_tab, scancode, keycode);
344 if (rc < 0)
345 return rc;
346 set_bit(keycode, dev->keybit);
347
348 return 0;
349}
350
351/**
352 * ir_g_keycode_from_table() - gets the keycode that corresponds to a scancode
353 * @input_dev: the struct input_dev descriptor of the device
354 * @scancode: the scancode that we're seeking
355 *
356 * This routine is used by the input routines when a key is pressed at the
357 * IR. The scancode is received and needs to be converted into a keycode.
358 * If the key is not found, it returns KEY_UNKNOWN. Otherwise, returns the
359 * corresponding keycode from the table.
360 */
361u32 ir_g_keycode_from_table(struct input_dev *dev, u32 scancode)
362{
363 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
364 struct ir_scancode *keymap = rc_tab->scan;
365 int elem;
366
367 elem = ir_seek_table(rc_tab, scancode);
368 if (elem >= 0) {
369 IR_dprintk(1, "%s: scancode 0x%04x keycode 0x%02x\n",
370 dev->name, scancode, keymap[elem].keycode);
371
372 return rc_tab->scan[elem].keycode;
373 }
374
375 printk(KERN_INFO "%s: unknown key for scancode 0x%04x\n",
376 dev->name, scancode);
377
378 /* Reports userspace that an unknown keycode were got */
379 return KEY_RESERVED;
380}
381
382/**
383 * ir_set_keycode_table() - sets the IR keycode table and add the handlers
384 * for keymap table get/set
385 * @input_dev: the struct input_dev descriptor of the device
386 * @rc_tab: the struct ir_scancode_table table of scancode/keymap
387 *
388 * This routine is used to initialize the input infrastructure to work with
389 * an IR.
390 * It should be called before registering the IR device.
391 */
392int ir_set_keycode_table(struct input_dev *input_dev,
393 struct ir_scancode_table *rc_tab)
394{
395 struct ir_scancode *keymap = rc_tab->scan;
396 int i;
397
398 spin_lock_init(&rc_tab->lock);
399
400 if (rc_tab->scan == NULL || !rc_tab->size)
401 return -EINVAL;
402
403 /* set the bits for the keys */
404 IR_dprintk(1, "key map size: %d\n", rc_tab->size);
405 for (i = 0; i < rc_tab->size; i++) {
406 IR_dprintk(1, "#%d: setting bit for keycode 0x%04x\n",
407 i, keymap[i].keycode);
408 set_bit(keymap[i].keycode, input_dev->keybit);
409 }
410
411 input_dev->getkeycode = ir_getkeycode;
412 input_dev->setkeycode = ir_setkeycode;
413 input_set_drvdata(input_dev, rc_tab);
414
415 return 0;
416}
417
418void ir_input_free(struct input_dev *dev)
419{
420 struct ir_scancode_table *rc_tab = input_get_drvdata(dev);
421
422 IR_dprintk(1, "Freed keycode table\n");
423
424 rc_tab->size = 0;
425 kfree(rc_tab->scan);
426 rc_tab->scan = NULL;
427}
428EXPORT_SYMBOL_GPL(ir_input_free);
429
diff --git a/drivers/media/common/saa7146_video.c b/drivers/media/common/saa7146_video.c
index 552dab442d78..becbaadb3b77 100644
--- a/drivers/media/common/saa7146_video.c
+++ b/drivers/media/common/saa7146_video.c
@@ -1205,6 +1205,13 @@ static int buffer_activate (struct saa7146_dev *dev,
1205 return 0; 1205 return 0;
1206} 1206}
1207 1207
1208static void release_all_pagetables(struct saa7146_dev *dev, struct saa7146_buf *buf)
1209{
1210 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1211 saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1212 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1213}
1214
1208static int buffer_prepare(struct videobuf_queue *q, 1215static int buffer_prepare(struct videobuf_queue *q,
1209 struct videobuf_buffer *vb, enum v4l2_field field) 1216 struct videobuf_buffer *vb, enum v4l2_field field)
1210{ 1217{
@@ -1257,16 +1264,12 @@ static int buffer_prepare(struct videobuf_queue *q,
1257 1264
1258 sfmt = format_by_fourcc(dev,buf->fmt->pixelformat); 1265 sfmt = format_by_fourcc(dev,buf->fmt->pixelformat);
1259 1266
1267 release_all_pagetables(dev, buf);
1260 if( 0 != IS_PLANAR(sfmt->trans)) { 1268 if( 0 != IS_PLANAR(sfmt->trans)) {
1261 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1262 saa7146_pgtable_free(dev->pci, &buf->pt[1]);
1263 saa7146_pgtable_free(dev->pci, &buf->pt[2]);
1264
1265 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1269 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1266 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]); 1270 saa7146_pgtable_alloc(dev->pci, &buf->pt[1]);
1267 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]); 1271 saa7146_pgtable_alloc(dev->pci, &buf->pt[2]);
1268 } else { 1272 } else {
1269 saa7146_pgtable_free(dev->pci, &buf->pt[0]);
1270 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]); 1273 saa7146_pgtable_alloc(dev->pci, &buf->pt[0]);
1271 } 1274 }
1272 1275
@@ -1329,6 +1332,9 @@ static void buffer_release(struct videobuf_queue *q, struct videobuf_buffer *vb)
1329 struct saa7146_buf *buf = (struct saa7146_buf *)vb; 1332 struct saa7146_buf *buf = (struct saa7146_buf *)vb;
1330 1333
1331 DEB_CAP(("vbuf:%p\n",vb)); 1334 DEB_CAP(("vbuf:%p\n",vb));
1335
1336 release_all_pagetables(dev, buf);
1337
1332 saa7146_dma_free(dev,q,buf); 1338 saa7146_dma_free(dev,q,buf);
1333} 1339}
1334 1340
diff --git a/drivers/media/common/tuners/Kconfig b/drivers/media/common/tuners/Kconfig
index 607d319ce8ed..409a4261e5b5 100644
--- a/drivers/media/common/tuners/Kconfig
+++ b/drivers/media/common/tuners/Kconfig
@@ -172,4 +172,11 @@ config MEDIA_TUNER_MC44S803
172 help 172 help
173 Say Y here to support the Freescale MC44S803 based tuners 173 Say Y here to support the Freescale MC44S803 based tuners
174 174
175config MEDIA_TUNER_MAX2165
176 tristate "Maxim MAX2165 silicon tuner"
177 depends on VIDEO_MEDIA && I2C
178 default m if MEDIA_TUNER_CUSTOMISE
179 help
180 A driver for the silicon tuner MAX2165 from Maxim.
181
175endif # MEDIA_TUNER_CUSTOMISE 182endif # MEDIA_TUNER_CUSTOMISE
diff --git a/drivers/media/common/tuners/Makefile b/drivers/media/common/tuners/Makefile
index 4132b2be79e5..a5438523f30d 100644
--- a/drivers/media/common/tuners/Makefile
+++ b/drivers/media/common/tuners/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_MEDIA_TUNER_MT2131) += mt2131.o
23obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o 23obj-$(CONFIG_MEDIA_TUNER_MXL5005S) += mxl5005s.o
24obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o 24obj-$(CONFIG_MEDIA_TUNER_MXL5007T) += mxl5007t.o
25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o 25obj-$(CONFIG_MEDIA_TUNER_MC44S803) += mc44s803.o
26obj-$(CONFIG_MEDIA_TUNER_MAX2165) += max2165.o
26 27
27EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core 28EXTRA_CFLAGS += -Idrivers/media/dvb/dvb-core
28EXTRA_CFLAGS += -Idrivers/media/dvb/frontends 29EXTRA_CFLAGS += -Idrivers/media/dvb/frontends
diff --git a/drivers/media/common/tuners/max2165.c b/drivers/media/common/tuners/max2165.c
new file mode 100644
index 000000000000..1b486cfb8ed9
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.c
@@ -0,0 +1,442 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#include <linux/module.h>
23#include <linux/moduleparam.h>
24#include <linux/videodev2.h>
25#include <linux/delay.h>
26#include <linux/dvb/frontend.h>
27#include <linux/i2c.h>
28
29#include "dvb_frontend.h"
30
31#include "max2165.h"
32#include "max2165_priv.h"
33#include "tuner-i2c.h"
34
35#define dprintk(args...) \
36 do { \
37 if (debug) \
38 printk(KERN_DEBUG "max2165: " args); \
39 } while (0)
40
41static int debug;
42module_param(debug, int, 0644);
43MODULE_PARM_DESC(debug, "Turn on/off debugging (default:off).");
44
45static int max2165_write_reg(struct max2165_priv *priv, u8 reg, u8 data)
46{
47 int ret;
48 u8 buf[] = { reg, data };
49 struct i2c_msg msg = { .flags = 0, .buf = buf, .len = 2 };
50
51 msg.addr = priv->config->i2c_address;
52
53 if (debug >= 2)
54 printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
55 __func__, reg, data);
56
57 ret = i2c_transfer(priv->i2c, &msg, 1);
58
59 if (ret != 1)
60 dprintk(KERN_DEBUG "%s: error reg=0x%x, data=0x%x, ret=%i\n",
61 __func__, reg, data, ret);
62
63 return (ret != 1) ? -EIO : 0;
64}
65
66static int max2165_read_reg(struct max2165_priv *priv, u8 reg, u8 *p_data)
67{
68 int ret;
69 u8 dev_addr = priv->config->i2c_address;
70
71 u8 b0[] = { reg };
72 u8 b1[] = { 0 };
73 struct i2c_msg msg[] = {
74 { .addr = dev_addr, .flags = 0, .buf = b0, .len = 1 },
75 { .addr = dev_addr, .flags = I2C_M_RD, .buf = b1, .len = 1 },
76 };
77
78 ret = i2c_transfer(priv->i2c, msg, 2);
79 if (ret != 2) {
80 dprintk(KERN_DEBUG "%s: error reg=0x%x, ret=%i\n",
81 __func__, reg, ret);
82 return -EIO;
83 }
84
85 *p_data = b1[0];
86 if (debug >= 2)
87 printk(KERN_DEBUG "%s: reg=0x%02X, data=0x%02X\n",
88 __func__, reg, b1[0]);
89 return 0;
90}
91
92static int max2165_mask_write_reg(struct max2165_priv *priv, u8 reg,
93 u8 mask, u8 data)
94{
95 int ret;
96 u8 v;
97
98 data &= mask;
99 ret = max2165_read_reg(priv, reg, &v);
100 if (ret != 0)
101 return ret;
102 v &= ~mask;
103 v |= data;
104 ret = max2165_write_reg(priv, reg, v);
105
106 return ret;
107}
108
109static int max2165_read_rom_table(struct max2165_priv *priv)
110{
111 u8 dat[3];
112 int i;
113
114 for (i = 0; i < 3; i++) {
115 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, i + 1);
116 max2165_read_reg(priv, REG_ROM_TABLE_DATA, &dat[i]);
117 }
118
119 priv->tf_ntch_low_cfg = dat[0] >> 4;
120 priv->tf_ntch_hi_cfg = dat[0] & 0x0F;
121 priv->tf_balun_low_ref = dat[1] & 0x0F;
122 priv->tf_balun_hi_ref = dat[1] >> 4;
123 priv->bb_filter_7mhz_cfg = dat[2] & 0x0F;
124 priv->bb_filter_8mhz_cfg = dat[2] >> 4;
125
126 dprintk("tf_ntch_low_cfg = 0x%X\n", priv->tf_ntch_low_cfg);
127 dprintk("tf_ntch_hi_cfg = 0x%X\n", priv->tf_ntch_hi_cfg);
128 dprintk("tf_balun_low_ref = 0x%X\n", priv->tf_balun_low_ref);
129 dprintk("tf_balun_hi_ref = 0x%X\n", priv->tf_balun_hi_ref);
130 dprintk("bb_filter_7mhz_cfg = 0x%X\n", priv->bb_filter_7mhz_cfg);
131 dprintk("bb_filter_8mhz_cfg = 0x%X\n", priv->bb_filter_8mhz_cfg);
132
133 return 0;
134}
135
136static int max2165_set_osc(struct max2165_priv *priv, u8 osc /*MHz*/)
137{
138 u8 v;
139
140 v = (osc / 2);
141 if (v == 2)
142 v = 0x7;
143 else
144 v -= 8;
145
146 max2165_mask_write_reg(priv, REG_PLL_CFG, 0x07, v);
147
148 return 0;
149}
150
151static int max2165_set_bandwidth(struct max2165_priv *priv, u32 bw)
152{
153 u8 val;
154
155 if (bw == BANDWIDTH_8_MHZ)
156 val = priv->bb_filter_8mhz_cfg;
157 else
158 val = priv->bb_filter_7mhz_cfg;
159
160 max2165_mask_write_reg(priv, REG_BASEBAND_CTRL, 0xF0, val << 4);
161
162 return 0;
163}
164
165int fixpt_div32(u32 dividend, u32 divisor, u32 *quotient, u32 *fraction)
166{
167 u32 remainder;
168 u32 q, f = 0;
169 int i;
170
171 if (0 == divisor)
172 return -1;
173
174 q = dividend / divisor;
175 remainder = dividend - q * divisor;
176
177 for (i = 0; i < 31; i++) {
178 remainder <<= 1;
179 if (remainder >= divisor) {
180 f += 1;
181 remainder -= divisor;
182 }
183 f <<= 1;
184 }
185
186 *quotient = q;
187 *fraction = f;
188
189 return 0;
190}
191
192static int max2165_set_rf(struct max2165_priv *priv, u32 freq)
193{
194 u8 tf;
195 u8 tf_ntch;
196 double t;
197 u32 quotient, fraction;
198
199 /* Set PLL divider according to RF frequency */
200 fixpt_div32(freq / 1000, priv->config->osc_clk * 1000,
201 &quotient, &fraction);
202
203 /* 20-bit fraction */
204 fraction >>= 12;
205
206 max2165_write_reg(priv, REG_NDIV_INT, quotient);
207 max2165_mask_write_reg(priv, REG_NDIV_FRAC2, 0x0F, fraction >> 16);
208 max2165_write_reg(priv, REG_NDIV_FRAC1, fraction >> 8);
209 max2165_write_reg(priv, REG_NDIV_FRAC0, fraction);
210
211 /* Norch Filter */
212 tf_ntch = (freq < 725000000) ?
213 priv->tf_ntch_low_cfg : priv->tf_ntch_hi_cfg;
214
215 /* Tracking filter balun */
216 t = priv->tf_balun_low_ref;
217 t += (priv->tf_balun_hi_ref - priv->tf_balun_low_ref)
218 * (freq / 1000 - 470000) / (780000 - 470000);
219
220 tf = t;
221 dprintk("tf = %X\n", tf);
222 tf |= tf_ntch << 4;
223
224 max2165_write_reg(priv, REG_TRACK_FILTER, tf);
225
226 return 0;
227}
228
229static void max2165_debug_status(struct max2165_priv *priv)
230{
231 u8 status, autotune;
232 u8 auto_vco_success, auto_vco_active;
233 u8 pll_locked;
234 u8 dc_offset_low, dc_offset_hi;
235 u8 signal_lv_over_threshold;
236 u8 vco, vco_sub_band, adc;
237
238 max2165_read_reg(priv, REG_STATUS, &status);
239 max2165_read_reg(priv, REG_AUTOTUNE, &autotune);
240
241 auto_vco_success = (status >> 6) & 0x01;
242 auto_vco_active = (status >> 5) & 0x01;
243 pll_locked = (status >> 4) & 0x01;
244 dc_offset_low = (status >> 3) & 0x01;
245 dc_offset_hi = (status >> 2) & 0x01;
246 signal_lv_over_threshold = status & 0x01;
247
248 vco = autotune >> 6;
249 vco_sub_band = (autotune >> 3) & 0x7;
250 adc = autotune & 0x7;
251
252 dprintk("auto VCO active: %d, auto VCO success: %d\n",
253 auto_vco_active, auto_vco_success);
254 dprintk("PLL locked: %d\n", pll_locked);
255 dprintk("DC offset low: %d, DC offset high: %d\n",
256 dc_offset_low, dc_offset_hi);
257 dprintk("Signal lvl over threshold: %d\n", signal_lv_over_threshold);
258 dprintk("VCO: %d, VCO Sub-band: %d, ADC: %d\n", vco, vco_sub_band, adc);
259}
260
261static int max2165_set_params(struct dvb_frontend *fe,
262 struct dvb_frontend_parameters *params)
263{
264 struct max2165_priv *priv = fe->tuner_priv;
265 int ret;
266
267 dprintk("%s() frequency=%d (Hz)\n", __func__, params->frequency);
268 if (fe->ops.info.type == FE_ATSC) {
269 return -EINVAL;
270 } else if (fe->ops.info.type == FE_OFDM) {
271 dprintk("%s() OFDM\n", __func__);
272 switch (params->u.ofdm.bandwidth) {
273 case BANDWIDTH_6_MHZ:
274 return -EINVAL;
275 case BANDWIDTH_7_MHZ:
276 case BANDWIDTH_8_MHZ:
277 priv->frequency = params->frequency;
278 priv->bandwidth = params->u.ofdm.bandwidth;
279 break;
280 default:
281 printk(KERN_ERR "MAX2165 bandwidth not set!\n");
282 return -EINVAL;
283 }
284 } else {
285 printk(KERN_ERR "MAX2165 modulation type not supported!\n");
286 return -EINVAL;
287 }
288
289 dprintk("%s() frequency=%d\n", __func__, priv->frequency);
290
291 if (fe->ops.i2c_gate_ctrl)
292 fe->ops.i2c_gate_ctrl(fe, 1);
293 max2165_set_bandwidth(priv, priv->bandwidth);
294 ret = max2165_set_rf(priv, priv->frequency);
295 mdelay(50);
296 max2165_debug_status(priv);
297 if (fe->ops.i2c_gate_ctrl)
298 fe->ops.i2c_gate_ctrl(fe, 0);
299
300 if (ret != 0)
301 return -EREMOTEIO;
302
303 return 0;
304}
305
306static int max2165_get_frequency(struct dvb_frontend *fe, u32 *freq)
307{
308 struct max2165_priv *priv = fe->tuner_priv;
309 dprintk("%s()\n", __func__);
310 *freq = priv->frequency;
311 return 0;
312}
313
314static int max2165_get_bandwidth(struct dvb_frontend *fe, u32 *bw)
315{
316 struct max2165_priv *priv = fe->tuner_priv;
317 dprintk("%s()\n", __func__);
318
319 *bw = priv->bandwidth;
320 return 0;
321}
322
323static int max2165_get_status(struct dvb_frontend *fe, u32 *status)
324{
325 struct max2165_priv *priv = fe->tuner_priv;
326 u16 lock_status = 0;
327
328 dprintk("%s()\n", __func__);
329
330 if (fe->ops.i2c_gate_ctrl)
331 fe->ops.i2c_gate_ctrl(fe, 1);
332
333 max2165_debug_status(priv);
334 *status = lock_status;
335
336 if (fe->ops.i2c_gate_ctrl)
337 fe->ops.i2c_gate_ctrl(fe, 0);
338
339 return 0;
340}
341
342static int max2165_sleep(struct dvb_frontend *fe)
343{
344 dprintk("%s()\n", __func__);
345 return 0;
346}
347
348static int max2165_init(struct dvb_frontend *fe)
349{
350 struct max2165_priv *priv = fe->tuner_priv;
351 dprintk("%s()\n", __func__);
352
353 if (fe->ops.i2c_gate_ctrl)
354 fe->ops.i2c_gate_ctrl(fe, 1);
355
356 /* Setup initial values */
357 /* Fractional Mode on */
358 max2165_write_reg(priv, REG_NDIV_FRAC2, 0x18);
359 /* LNA on */
360 max2165_write_reg(priv, REG_LNA, 0x01);
361 max2165_write_reg(priv, REG_PLL_CFG, 0x7A);
362 max2165_write_reg(priv, REG_TEST, 0x08);
363 max2165_write_reg(priv, REG_SHUTDOWN, 0x40);
364 max2165_write_reg(priv, REG_VCO_CTRL, 0x84);
365 max2165_write_reg(priv, REG_BASEBAND_CTRL, 0xC3);
366 max2165_write_reg(priv, REG_DC_OFFSET_CTRL, 0x75);
367 max2165_write_reg(priv, REG_DC_OFFSET_DAC, 0x00);
368 max2165_write_reg(priv, REG_ROM_TABLE_ADDR, 0x00);
369
370 max2165_set_osc(priv, priv->config->osc_clk);
371
372 max2165_read_rom_table(priv);
373
374 max2165_set_bandwidth(priv, BANDWIDTH_8_MHZ);
375
376 if (fe->ops.i2c_gate_ctrl)
377 fe->ops.i2c_gate_ctrl(fe, 0);
378
379 return 0;
380}
381
382static int max2165_release(struct dvb_frontend *fe)
383{
384 struct max2165_priv *priv = fe->tuner_priv;
385 dprintk("%s()\n", __func__);
386
387 kfree(priv);
388 fe->tuner_priv = NULL;
389
390 return 0;
391}
392
393static const struct dvb_tuner_ops max2165_tuner_ops = {
394 .info = {
395 .name = "Maxim MAX2165",
396 .frequency_min = 470000000,
397 .frequency_max = 780000000,
398 .frequency_step = 50000,
399 },
400
401 .release = max2165_release,
402 .init = max2165_init,
403 .sleep = max2165_sleep,
404
405 .set_params = max2165_set_params,
406 .set_analog_params = NULL,
407 .get_frequency = max2165_get_frequency,
408 .get_bandwidth = max2165_get_bandwidth,
409 .get_status = max2165_get_status
410};
411
412struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
413 struct i2c_adapter *i2c,
414 struct max2165_config *cfg)
415{
416 struct max2165_priv *priv = NULL;
417
418 dprintk("%s(%d-%04x)\n", __func__,
419 i2c ? i2c_adapter_id(i2c) : -1,
420 cfg ? cfg->i2c_address : -1);
421
422 priv = kzalloc(sizeof(struct max2165_priv), GFP_KERNEL);
423 if (priv == NULL)
424 return NULL;
425
426 memcpy(&fe->ops.tuner_ops, &max2165_tuner_ops,
427 sizeof(struct dvb_tuner_ops));
428
429 priv->config = cfg;
430 priv->i2c = i2c;
431 fe->tuner_priv = priv;
432
433 max2165_init(fe);
434 max2165_debug_status(priv);
435
436 return fe;
437}
438EXPORT_SYMBOL(max2165_attach);
439
440MODULE_AUTHOR("David T. L. Wong <davidtlwong@gmail.com>");
441MODULE_DESCRIPTION("Maxim MAX2165 silicon tuner driver");
442MODULE_LICENSE("GPL");
diff --git a/drivers/media/common/tuners/max2165.h b/drivers/media/common/tuners/max2165.h
new file mode 100644
index 000000000000..c063c36a93d3
--- /dev/null
+++ b/drivers/media/common/tuners/max2165.h
@@ -0,0 +1,48 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_H__
23#define __MAX2165_H__
24
25struct dvb_frontend;
26struct i2c_adapter;
27
28struct max2165_config {
29 u8 i2c_address;
30 u8 osc_clk; /* in MHz, selectable values: 4,16,18,20,22,24,26,28 */
31};
32
33#if defined(CONFIG_MEDIA_TUNER_MAX2165) || \
34 (defined(CONFIG_MEDIA_TUNER_MAX2165_MODULE) && defined(MODULE))
35extern struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
36 struct i2c_adapter *i2c,
37 struct max2165_config *cfg);
38#else
39static inline struct dvb_frontend *max2165_attach(struct dvb_frontend *fe,
40 struct i2c_adapter *i2c,
41 struct max2165_config *cfg)
42{
43 printk(KERN_WARNING "%s: driver disabled by Kconfig\n", __func__);
44 return NULL;
45}
46#endif
47
48#endif
diff --git a/drivers/media/common/tuners/max2165_priv.h b/drivers/media/common/tuners/max2165_priv.h
new file mode 100644
index 000000000000..91bbe021a08d
--- /dev/null
+++ b/drivers/media/common/tuners/max2165_priv.h
@@ -0,0 +1,60 @@
1/*
2 * Driver for Maxim MAX2165 silicon tuner
3 *
4 * Copyright (c) 2009 David T. L. Wong <davidtlwong@gmail.com>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 *
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21
22#ifndef __MAX2165_PRIV_H__
23#define __MAX2165_PRIV_H__
24
25#define REG_NDIV_INT 0x00
26#define REG_NDIV_FRAC2 0x01
27#define REG_NDIV_FRAC1 0x02
28#define REG_NDIV_FRAC0 0x03
29#define REG_TRACK_FILTER 0x04
30#define REG_LNA 0x05
31#define REG_PLL_CFG 0x06
32#define REG_TEST 0x07
33#define REG_SHUTDOWN 0x08
34#define REG_VCO_CTRL 0x09
35#define REG_BASEBAND_CTRL 0x0A
36#define REG_DC_OFFSET_CTRL 0x0B
37#define REG_DC_OFFSET_DAC 0x0C
38#define REG_ROM_TABLE_ADDR 0x0D
39
40/* Read Only Registers */
41#define REG_ROM_TABLE_DATA 0x10
42#define REG_STATUS 0x11
43#define REG_AUTOTUNE 0x12
44
45struct max2165_priv {
46 struct max2165_config *config;
47 struct i2c_adapter *i2c;
48
49 u32 frequency;
50 u32 bandwidth;
51
52 u8 tf_ntch_low_cfg;
53 u8 tf_ntch_hi_cfg;
54 u8 tf_balun_low_ref;
55 u8 tf_balun_hi_ref;
56 u8 bb_filter_7mhz_cfg;
57 u8 bb_filter_8mhz_cfg;
58};
59
60#endif
diff --git a/drivers/media/common/tuners/mxl5005s.c b/drivers/media/common/tuners/mxl5005s.c
index 0803dab58fff..605e28b73263 100644
--- a/drivers/media/common/tuners/mxl5005s.c
+++ b/drivers/media/common/tuners/mxl5005s.c
@@ -2789,7 +2789,10 @@ static u16 MXL_TuneRF(struct dvb_frontend *fe, u32 RF_Freq)
2789 2789
2790 /* add for 2.6.5 Special setting for QAM */ 2790 /* add for 2.6.5 Special setting for QAM */
2791 if (state->Mod_Type == MXL_QAM) { 2791 if (state->Mod_Type == MXL_QAM) {
2792 if (state->RF_IN < 680000000) 2792 if (state->config->qam_gain != 0)
2793 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN,
2794 state->config->qam_gain);
2795 else if (state->RF_IN < 680000000)
2793 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3); 2796 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 3);
2794 else 2797 else
2795 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2); 2798 status += MXL_ControlWrite(fe, RFSYN_CHP_GAIN, 2);
diff --git a/drivers/media/common/tuners/mxl5005s.h b/drivers/media/common/tuners/mxl5005s.h
index 7ac6815b30aa..fc8a1ffc53b4 100644
--- a/drivers/media/common/tuners/mxl5005s.h
+++ b/drivers/media/common/tuners/mxl5005s.h
@@ -108,6 +108,10 @@ struct mxl5005s_config {
108#define MXL_LOW_IF 1 108#define MXL_LOW_IF 1
109 u8 if_mode; 109 u8 if_mode;
110 110
111 /* Some boards need to override the built-in logic for determining
112 the gain when in QAM mode (the HVR-1600 is one such case) */
113 u8 qam_gain;
114
111 /* Stuff I don't know what to do with */ 115 /* Stuff I don't know what to do with */
112 u8 AgcMasterByte; 116 u8 AgcMasterByte;
113}; 117};
diff --git a/drivers/media/common/tuners/mxl5007t.c b/drivers/media/common/tuners/mxl5007t.c
index 2d02698d4f4f..7eb1bf75cd07 100644
--- a/drivers/media/common/tuners/mxl5007t.c
+++ b/drivers/media/common/tuners/mxl5007t.c
@@ -196,7 +196,7 @@ static void copy_reg_bits(struct reg_pair_t *reg_pair1,
196 i = j = 0; 196 i = j = 0;
197 197
198 while (reg_pair1[i].reg || reg_pair1[i].val) { 198 while (reg_pair1[i].reg || reg_pair1[i].val) {
199 while (reg_pair2[j].reg || reg_pair2[j].reg) { 199 while (reg_pair2[j].reg || reg_pair2[j].val) {
200 if (reg_pair1[i].reg != reg_pair2[j].reg) { 200 if (reg_pair1[i].reg != reg_pair2[j].reg) {
201 j++; 201 j++;
202 continue; 202 continue;
diff --git a/drivers/media/common/tuners/tda18271-common.c b/drivers/media/common/tuners/tda18271-common.c
index 155c93eb75da..e1f678281a58 100644
--- a/drivers/media/common/tuners/tda18271-common.c
+++ b/drivers/media/common/tuners/tda18271-common.c
@@ -326,12 +326,24 @@ int tda18271_init_regs(struct dvb_frontend *fe)
326 regs[R_EB22] = 0x48; 326 regs[R_EB22] = 0x48;
327 regs[R_EB23] = 0xb0; 327 regs[R_EB23] = 0xb0;
328 328
329 if (priv->small_i2c) { 329 switch (priv->small_i2c) {
330 case TDA18271_08_BYTE_CHUNK_INIT:
331 tda18271_write_regs(fe, 0x00, 0x08);
332 tda18271_write_regs(fe, 0x08, 0x08);
333 tda18271_write_regs(fe, 0x10, 0x08);
334 tda18271_write_regs(fe, 0x18, 0x08);
335 tda18271_write_regs(fe, 0x20, 0x07);
336 break;
337 case TDA18271_16_BYTE_CHUNK_INIT:
330 tda18271_write_regs(fe, 0x00, 0x10); 338 tda18271_write_regs(fe, 0x00, 0x10);
331 tda18271_write_regs(fe, 0x10, 0x10); 339 tda18271_write_regs(fe, 0x10, 0x10);
332 tda18271_write_regs(fe, 0x20, 0x07); 340 tda18271_write_regs(fe, 0x20, 0x07);
333 } else 341 break;
342 case TDA18271_39_BYTE_CHUNK_INIT:
343 default:
334 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS); 344 tda18271_write_regs(fe, 0x00, TDA18271_NUM_REGS);
345 break;
346 }
335 347
336 /* setup agc1 gain */ 348 /* setup agc1 gain */
337 regs[R_EB17] = 0x00; 349 regs[R_EB17] = 0x00;
diff --git a/drivers/media/common/tuners/tda18271-fe.c b/drivers/media/common/tuners/tda18271-fe.c
index 3a50ce96fcb9..b2e15456d5f3 100644
--- a/drivers/media/common/tuners/tda18271-fe.c
+++ b/drivers/media/common/tuners/tda18271-fe.c
@@ -256,8 +256,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
256 struct tda18271_priv *priv = fe->tuner_priv; 256 struct tda18271_priv *priv = fe->tuner_priv;
257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; 257 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
258 unsigned char *regs = priv->tda18271_regs; 258 unsigned char *regs = priv->tda18271_regs;
259 int tm_current, rfcal_comp, approx, i, ret; 259 int i, ret;
260 u8 dc_over_dt, rf_tab; 260 u8 tm_current, dc_over_dt, rf_tab;
261 s32 rfcal_comp, approx;
261 262
262 /* power up */ 263 /* power up */
263 ret = tda18271_set_standby_mode(fe, 0, 0, 0); 264 ret = tda18271_set_standby_mode(fe, 0, 0, 0);
@@ -277,11 +278,11 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
277 return i; 278 return i;
278 279
279 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) { 280 if ((0 == map[i].rf3) || (freq / 1000 < map[i].rf2)) {
280 approx = map[i].rf_a1 * 281 approx = map[i].rf_a1 * (s32)(freq / 1000 - map[i].rf1) +
281 (freq / 1000 - map[i].rf1) + map[i].rf_b1 + rf_tab; 282 map[i].rf_b1 + rf_tab;
282 } else { 283 } else {
283 approx = map[i].rf_a2 * 284 approx = map[i].rf_a2 * (s32)(freq / 1000 - map[i].rf2) +
284 (freq / 1000 - map[i].rf2) + map[i].rf_b2 + rf_tab; 285 map[i].rf_b2 + rf_tab;
285 } 286 }
286 287
287 if (approx < 0) 288 if (approx < 0)
@@ -292,9 +293,9 @@ static int tda18271c2_rf_tracking_filters_correction(struct dvb_frontend *fe,
292 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt); 293 tda18271_lookup_map(fe, RF_CAL_DC_OVER_DT, &freq, &dc_over_dt);
293 294
294 /* calculate temperature compensation */ 295 /* calculate temperature compensation */
295 rfcal_comp = dc_over_dt * (tm_current - priv->tm_rfcal) / 1000; 296 rfcal_comp = dc_over_dt * (s32)(tm_current - priv->tm_rfcal) / 1000;
296 297
297 regs[R_EB14] = approx + rfcal_comp; 298 regs[R_EB14] = (unsigned char)(approx + rfcal_comp);
298 ret = tda18271_write_regs(fe, R_EB14, 1); 299 ret = tda18271_write_regs(fe, R_EB14, 1);
299fail: 300fail:
300 return ret; 301 return ret;
@@ -572,6 +573,7 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
572 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state; 573 struct tda18271_rf_tracking_filter_cal *map = priv->rf_cal_state;
573 unsigned char *regs = priv->tda18271_regs; 574 unsigned char *regs = priv->tda18271_regs;
574 int bcal, rf, i; 575 int bcal, rf, i;
576 s32 divisor, dividend;
575#define RF1 0 577#define RF1 0
576#define RF2 1 578#define RF2 1
577#define RF3 2 579#define RF3 2
@@ -610,20 +612,22 @@ static int tda18271_rf_tracking_filters_init(struct dvb_frontend *fe, u32 freq)
610 switch (rf) { 612 switch (rf) {
611 case RF1: 613 case RF1:
612 map[i].rf_a1 = 0; 614 map[i].rf_a1 = 0;
613 map[i].rf_b1 = prog_cal[RF1] - prog_tab[RF1]; 615 map[i].rf_b1 = (s32)(prog_cal[RF1] - prog_tab[RF1]);
614 map[i].rf1 = rf_freq[RF1] / 1000; 616 map[i].rf1 = rf_freq[RF1] / 1000;
615 break; 617 break;
616 case RF2: 618 case RF2:
617 map[i].rf_a1 = (prog_cal[RF2] - prog_tab[RF2] - 619 dividend = (s32)(prog_cal[RF2] - prog_tab[RF2]) -
618 prog_cal[RF1] + prog_tab[RF1]) / 620 (s32)(prog_cal[RF1] + prog_tab[RF1]);
619 (s32)((rf_freq[RF2] - rf_freq[RF1]) / 1000); 621 divisor = (s32)(rf_freq[RF2] - rf_freq[RF1]) / 1000;
622 map[i].rf_a1 = (dividend / divisor);
620 map[i].rf2 = rf_freq[RF2] / 1000; 623 map[i].rf2 = rf_freq[RF2] / 1000;
621 break; 624 break;
622 case RF3: 625 case RF3:
623 map[i].rf_a2 = (prog_cal[RF3] - prog_tab[RF3] - 626 dividend = (s32)(prog_cal[RF3] - prog_tab[RF3]) -
624 prog_cal[RF2] + prog_tab[RF2]) / 627 (s32)(prog_cal[RF2] + prog_tab[RF2]);
625 (s32)((rf_freq[RF3] - rf_freq[RF2]) / 1000); 628 divisor = (s32)(rf_freq[RF3] - rf_freq[RF2]) / 1000;
626 map[i].rf_b2 = prog_cal[RF2] - prog_tab[RF2]; 629 map[i].rf_a2 = (dividend / divisor);
630 map[i].rf_b2 = (s32)(prog_cal[RF2] - prog_tab[RF2]);
627 map[i].rf3 = rf_freq[RF3] / 1000; 631 map[i].rf3 = rf_freq[RF3] / 1000;
628 break; 632 break;
629 default: 633 default:
@@ -1181,6 +1185,48 @@ static int tda18271_get_id(struct dvb_frontend *fe)
1181 return ret; 1185 return ret;
1182} 1186}
1183 1187
1188static int tda18271_setup_configuration(struct dvb_frontend *fe,
1189 struct tda18271_config *cfg)
1190{
1191 struct tda18271_priv *priv = fe->tuner_priv;
1192
1193 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO;
1194 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1195 priv->config = (cfg) ? cfg->config : 0;
1196 priv->small_i2c = (cfg) ?
1197 cfg->small_i2c : TDA18271_39_BYTE_CHUNK_INIT;
1198 priv->output_opt = (cfg) ?
1199 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1200
1201 return 0;
1202}
1203
1204static inline int tda18271_need_cal_on_startup(struct tda18271_config *cfg)
1205{
1206 /* tda18271_cal_on_startup == -1 when cal module option is unset */
1207 return ((tda18271_cal_on_startup == -1) ?
1208 /* honor configuration setting */
1209 ((cfg) && (cfg->rf_cal_on_startup)) :
1210 /* module option overrides configuration setting */
1211 (tda18271_cal_on_startup)) ? 1 : 0;
1212}
1213
1214static int tda18271_set_config(struct dvb_frontend *fe, void *priv_cfg)
1215{
1216 struct tda18271_config *cfg = (struct tda18271_config *) priv_cfg;
1217
1218 tda18271_setup_configuration(fe, cfg);
1219
1220 if (tda18271_need_cal_on_startup(cfg))
1221 tda18271_init(fe);
1222
1223 /* override default std map with values in config struct */
1224 if ((cfg) && (cfg->std_map))
1225 tda18271_update_std_map(fe, cfg->std_map);
1226
1227 return 0;
1228}
1229
1184static struct dvb_tuner_ops tda18271_tuner_ops = { 1230static struct dvb_tuner_ops tda18271_tuner_ops = {
1185 .info = { 1231 .info = {
1186 .name = "NXP TDA18271HD", 1232 .name = "NXP TDA18271HD",
@@ -1193,6 +1239,7 @@ static struct dvb_tuner_ops tda18271_tuner_ops = {
1193 .set_params = tda18271_set_params, 1239 .set_params = tda18271_set_params,
1194 .set_analog_params = tda18271_set_analog_params, 1240 .set_analog_params = tda18271_set_analog_params,
1195 .release = tda18271_release, 1241 .release = tda18271_release,
1242 .set_config = tda18271_set_config,
1196 .get_frequency = tda18271_get_frequency, 1243 .get_frequency = tda18271_get_frequency,
1197 .get_bandwidth = tda18271_get_bandwidth, 1244 .get_bandwidth = tda18271_get_bandwidth,
1198}; 1245};
@@ -1213,33 +1260,14 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1213 case 0: 1260 case 0:
1214 goto fail; 1261 goto fail;
1215 case 1: 1262 case 1:
1216 {
1217 /* new tuner instance */ 1263 /* new tuner instance */
1218 int rf_cal_on_startup; 1264 fe->tuner_priv = priv;
1219 1265
1220 priv->gate = (cfg) ? cfg->gate : TDA18271_GATE_AUTO; 1266 tda18271_setup_configuration(fe, cfg);
1221 priv->role = (cfg) ? cfg->role : TDA18271_MASTER;
1222 priv->config = (cfg) ? cfg->config : 0;
1223 priv->small_i2c = (cfg) ? cfg->small_i2c : 0;
1224 priv->output_opt = (cfg) ?
1225 cfg->output_opt : TDA18271_OUTPUT_LT_XT_ON;
1226
1227 /* tda18271_cal_on_startup == -1 when cal
1228 * module option is unset */
1229 if (tda18271_cal_on_startup == -1) {
1230 /* honor attach-time configuration */
1231 rf_cal_on_startup =
1232 ((cfg) && (cfg->rf_cal_on_startup)) ? 1 : 0;
1233 } else {
1234 /* module option overrides attach configuration */
1235 rf_cal_on_startup = tda18271_cal_on_startup;
1236 }
1237 1267
1238 priv->cal_initialized = false; 1268 priv->cal_initialized = false;
1239 mutex_init(&priv->lock); 1269 mutex_init(&priv->lock);
1240 1270
1241 fe->tuner_priv = priv;
1242
1243 if (tda_fail(tda18271_get_id(fe))) 1271 if (tda_fail(tda18271_get_id(fe)))
1244 goto fail; 1272 goto fail;
1245 1273
@@ -1249,12 +1277,12 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1249 mutex_lock(&priv->lock); 1277 mutex_lock(&priv->lock);
1250 tda18271_init_regs(fe); 1278 tda18271_init_regs(fe);
1251 1279
1252 if ((rf_cal_on_startup) && (priv->id == TDA18271HDC2)) 1280 if ((tda18271_need_cal_on_startup(cfg)) &&
1281 (priv->id == TDA18271HDC2))
1253 tda18271c2_rf_cal_init(fe); 1282 tda18271c2_rf_cal_init(fe);
1254 1283
1255 mutex_unlock(&priv->lock); 1284 mutex_unlock(&priv->lock);
1256 break; 1285 break;
1257 }
1258 default: 1286 default:
1259 /* existing tuner instance */ 1287 /* existing tuner instance */
1260 fe->tuner_priv = priv; 1288 fe->tuner_priv = priv;
@@ -1271,7 +1299,11 @@ struct dvb_frontend *tda18271_attach(struct dvb_frontend *fe, u8 addr,
1271 priv->small_i2c = cfg->small_i2c; 1299 priv->small_i2c = cfg->small_i2c;
1272 if (cfg->output_opt) 1300 if (cfg->output_opt)
1273 priv->output_opt = cfg->output_opt; 1301 priv->output_opt = cfg->output_opt;
1302 if (cfg->std_map)
1303 tda18271_update_std_map(fe, cfg->std_map);
1274 } 1304 }
1305 if (tda18271_need_cal_on_startup(cfg))
1306 tda18271_init(fe);
1275 break; 1307 break;
1276 } 1308 }
1277 1309
@@ -1298,7 +1330,7 @@ EXPORT_SYMBOL_GPL(tda18271_attach);
1298MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver"); 1330MODULE_DESCRIPTION("NXP TDA18271HD analog / digital tuner driver");
1299MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>"); 1331MODULE_AUTHOR("Michael Krufky <mkrufky@linuxtv.org>");
1300MODULE_LICENSE("GPL"); 1332MODULE_LICENSE("GPL");
1301MODULE_VERSION("0.3"); 1333MODULE_VERSION("0.4");
1302 1334
1303/* 1335/*
1304 * Overrides for Emacs so that we follow Linus's tabbing style. 1336 * Overrides for Emacs so that we follow Linus's tabbing style.
diff --git a/drivers/media/common/tuners/tda18271-maps.c b/drivers/media/common/tuners/tda18271-maps.c
index e21fdeff3ddf..e7f84c705da8 100644
--- a/drivers/media/common/tuners/tda18271-maps.c
+++ b/drivers/media/common/tuners/tda18271-maps.c
@@ -978,6 +978,7 @@ static struct tda18271_cid_target_map tda18271_cid_target[] = {
978int tda18271_lookup_cid_target(struct dvb_frontend *fe, 978int tda18271_lookup_cid_target(struct dvb_frontend *fe,
979 u32 *freq, u8 *cid_target, u16 *count_limit) 979 u32 *freq, u8 *cid_target, u16 *count_limit)
980{ 980{
981 struct tda18271_priv *priv = fe->tuner_priv;
981 int i = 0; 982 int i = 0;
982 983
983 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) { 984 while ((tda18271_cid_target[i].rfmax * 1000) < *freq) {
diff --git a/drivers/media/common/tuners/tda18271-priv.h b/drivers/media/common/tuners/tda18271-priv.h
index 2bee229acd91..9589ab0576d2 100644
--- a/drivers/media/common/tuners/tda18271-priv.h
+++ b/drivers/media/common/tuners/tda18271-priv.h
@@ -80,10 +80,10 @@ struct tda18271_rf_tracking_filter_cal {
80 u32 rf1; 80 u32 rf1;
81 u32 rf2; 81 u32 rf2;
82 u32 rf3; 82 u32 rf3;
83 int rf_a1; 83 s32 rf_a1;
84 int rf_b1; 84 s32 rf_b1;
85 int rf_a2; 85 s32 rf_a2;
86 int rf_b2; 86 s32 rf_b2;
87}; 87};
88 88
89enum tda18271_pll { 89enum tda18271_pll {
@@ -109,11 +109,12 @@ struct tda18271_priv {
109 enum tda18271_i2c_gate gate; 109 enum tda18271_i2c_gate gate;
110 enum tda18271_ver id; 110 enum tda18271_ver id;
111 enum tda18271_output_options output_opt; 111 enum tda18271_output_options output_opt;
112 enum tda18271_small_i2c small_i2c;
112 113
113 unsigned int config; /* interface to saa713x / tda829x */ 114 unsigned int config; /* interface to saa713x / tda829x */
114 unsigned int tm_rfcal;
115 unsigned int cal_initialized:1; 115 unsigned int cal_initialized:1;
116 unsigned int small_i2c:1; 116
117 u8 tm_rfcal;
117 118
118 struct tda18271_map_layout *maps; 119 struct tda18271_map_layout *maps;
119 struct tda18271_std_map std; 120 struct tda18271_std_map std;
@@ -135,27 +136,37 @@ extern int tda18271_debug;
135#define DBG_ADV 8 136#define DBG_ADV 8
136#define DBG_CAL 16 137#define DBG_CAL 16
137 138
138#define tda_printk(kern, fmt, arg...) \ 139#define tda_printk(st, kern, fmt, arg...) do {\
139 printk(kern "%s: " fmt, __func__, ##arg) 140 if (st) { \
140 141 struct tda18271_priv *state = st; \
141#define tda_dprintk(lvl, fmt, arg...) do {\ 142 printk(kern "%s: [%d-%04x|%s] " fmt, __func__, \
143 i2c_adapter_id(state->i2c_props.adap), \
144 state->i2c_props.addr, \
145 (state->role == TDA18271_MASTER) \
146 ? "M" : "S", ##arg); \
147 } else \
148 printk(kern "%s: " fmt, __func__, ##arg); \
149} while (0)
150
151#define tda_dprintk(st, lvl, fmt, arg...) do {\
142 if (tda18271_debug & lvl) \ 152 if (tda18271_debug & lvl) \
143 tda_printk(KERN_DEBUG, fmt, ##arg); } while (0) 153 tda_printk(st, KERN_DEBUG, fmt, ##arg); } while (0)
144 154
145#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg) 155#define tda_info(fmt, arg...) printk(KERN_INFO fmt, ##arg)
146#define tda_warn(fmt, arg...) tda_printk(KERN_WARNING, fmt, ##arg) 156#define tda_warn(fmt, arg...) tda_printk(priv, KERN_WARNING, fmt, ##arg)
147#define tda_err(fmt, arg...) tda_printk(KERN_ERR, fmt, ##arg) 157#define tda_err(fmt, arg...) tda_printk(priv, KERN_ERR, fmt, ##arg)
148#define tda_dbg(fmt, arg...) tda_dprintk(DBG_INFO, fmt, ##arg) 158#define tda_dbg(fmt, arg...) tda_dprintk(priv, DBG_INFO, fmt, ##arg)
149#define tda_map(fmt, arg...) tda_dprintk(DBG_MAP, fmt, ##arg) 159#define tda_map(fmt, arg...) tda_dprintk(priv, DBG_MAP, fmt, ##arg)
150#define tda_reg(fmt, arg...) tda_dprintk(DBG_REG, fmt, ##arg) 160#define tda_reg(fmt, arg...) tda_dprintk(priv, DBG_REG, fmt, ##arg)
151#define tda_cal(fmt, arg...) tda_dprintk(DBG_CAL, fmt, ##arg) 161#define tda_cal(fmt, arg...) tda_dprintk(priv, DBG_CAL, fmt, ##arg)
152 162
153#define tda_fail(ret) \ 163#define tda_fail(ret) \
154({ \ 164({ \
155 int __ret; \ 165 int __ret; \
156 __ret = (ret < 0); \ 166 __ret = (ret < 0); \
157 if (__ret) \ 167 if (__ret) \
158 tda_printk(KERN_ERR, "error %d on line %d\n", ret, __LINE__);\ 168 tda_printk(priv, KERN_ERR, \
169 "error %d on line %d\n", ret, __LINE__); \
159 __ret; \ 170 __ret; \
160}) 171})
161 172
diff --git a/drivers/media/common/tuners/tda18271.h b/drivers/media/common/tuners/tda18271.h
index 323f2912128d..d7fcc36dc6e6 100644
--- a/drivers/media/common/tuners/tda18271.h
+++ b/drivers/media/common/tuners/tda18271.h
@@ -78,6 +78,12 @@ enum tda18271_output_options {
78 TDA18271_OUTPUT_XT_OFF = 2, 78 TDA18271_OUTPUT_XT_OFF = 2,
79}; 79};
80 80
81enum tda18271_small_i2c {
82 TDA18271_39_BYTE_CHUNK_INIT = 0,
83 TDA18271_16_BYTE_CHUNK_INIT = 1,
84 TDA18271_08_BYTE_CHUNK_INIT = 2,
85};
86
81struct tda18271_config { 87struct tda18271_config {
82 /* override default if freq / std settings (optional) */ 88 /* override default if freq / std settings (optional) */
83 struct tda18271_std_map *std_map; 89 struct tda18271_std_map *std_map;
@@ -91,12 +97,12 @@ struct tda18271_config {
91 /* output options that can be disabled */ 97 /* output options that can be disabled */
92 enum tda18271_output_options output_opt; 98 enum tda18271_output_options output_opt;
93 99
100 /* some i2c providers cant write all 39 registers at once */
101 enum tda18271_small_i2c small_i2c;
102
94 /* force rf tracking filter calibration on startup */ 103 /* force rf tracking filter calibration on startup */
95 unsigned int rf_cal_on_startup:1; 104 unsigned int rf_cal_on_startup:1;
96 105
97 /* some i2c providers cant write all 39 registers at once */
98 unsigned int small_i2c:1;
99
100 /* interface to saa713x / tda829x */ 106 /* interface to saa713x / tda829x */
101 unsigned int config; 107 unsigned int config;
102}; 108};
diff --git a/drivers/media/common/tuners/tda8290.c b/drivers/media/common/tuners/tda8290.c
index 064d14c8d7b2..c190b0dedee4 100644
--- a/drivers/media/common/tuners/tda8290.c
+++ b/drivers/media/common/tuners/tda8290.c
@@ -33,6 +33,7 @@ module_param(debug, int, 0644);
33MODULE_PARM_DESC(debug, "enable verbose debug messages"); 33MODULE_PARM_DESC(debug, "enable verbose debug messages");
34 34
35static int deemphasis_50; 35static int deemphasis_50;
36module_param(deemphasis_50, int, 0644);
36MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis"); 37MODULE_PARM_DESC(deemphasis_50, "0 - 75us deemphasis; 1 - 50us deemphasis");
37 38
38/* ---------------------------------------------------------------------- */ 39/* ---------------------------------------------------------------------- */
diff --git a/drivers/media/common/tuners/tda9887.c b/drivers/media/common/tuners/tda9887.c
index 544cdbe88a6c..a71c100c95df 100644
--- a/drivers/media/common/tuners/tda9887.c
+++ b/drivers/media/common/tuners/tda9887.c
@@ -463,7 +463,7 @@ static int tda9887_set_insmod(struct dvb_frontend *fe)
463 buf[1] &= ~cQSS; 463 buf[1] &= ~cQSS;
464 } 464 }
465 465
466 if (adjust >= 0x00 && adjust < 0x20) { 466 if (adjust < 0x20) {
467 buf[2] &= ~cTopMask; 467 buf[2] &= ~cTopMask;
468 buf[2] |= adjust; 468 buf[2] |= adjust;
469 } 469 }
diff --git a/drivers/media/common/tuners/xc5000.c b/drivers/media/common/tuners/xc5000.c
index f4ffcdc9b848..432003dded7c 100644
--- a/drivers/media/common/tuners/xc5000.c
+++ b/drivers/media/common/tuners/xc5000.c
@@ -61,6 +61,7 @@ struct xc5000_priv {
61 u32 bandwidth; 61 u32 bandwidth;
62 u8 video_standard; 62 u8 video_standard;
63 u8 rf_mode; 63 u8 rf_mode;
64 u8 radio_input;
64}; 65};
65 66
66/* Misc Defines */ 67/* Misc Defines */
@@ -632,8 +633,12 @@ static int xc5000_set_params(struct dvb_frontend *fe,
632 struct xc5000_priv *priv = fe->tuner_priv; 633 struct xc5000_priv *priv = fe->tuner_priv;
633 int ret; 634 int ret;
634 635
635 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) 636 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
636 xc_load_fw_and_init_tuner(fe); 637 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
638 dprintk(1, "Unable to load firmware and init tuner\n");
639 return -EINVAL;
640 }
641 }
637 642
638 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency); 643 dprintk(1, "%s() frequency=%d (Hz)\n", __func__, params->frequency);
639 644
@@ -739,15 +744,12 @@ static int xc5000_is_firmware_loaded(struct dvb_frontend *fe)
739 return ret; 744 return ret;
740} 745}
741 746
742static int xc5000_set_analog_params(struct dvb_frontend *fe, 747static int xc5000_set_tv_freq(struct dvb_frontend *fe,
743 struct analog_parameters *params) 748 struct analog_parameters *params)
744{ 749{
745 struct xc5000_priv *priv = fe->tuner_priv; 750 struct xc5000_priv *priv = fe->tuner_priv;
746 int ret; 751 int ret;
747 752
748 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS)
749 xc_load_fw_and_init_tuner(fe);
750
751 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n", 753 dprintk(1, "%s() frequency=%d (in units of 62.5khz)\n",
752 __func__, params->frequency); 754 __func__, params->frequency);
753 755
@@ -827,6 +829,86 @@ tune_channel:
827 return 0; 829 return 0;
828} 830}
829 831
832static int xc5000_set_radio_freq(struct dvb_frontend *fe,
833 struct analog_parameters *params)
834{
835 struct xc5000_priv *priv = fe->tuner_priv;
836 int ret = -EINVAL;
837 u8 radio_input;
838
839 dprintk(1, "%s() frequency=%d (in units of khz)\n",
840 __func__, params->frequency);
841
842 if (priv->radio_input == XC5000_RADIO_NOT_CONFIGURED) {
843 dprintk(1, "%s() radio input not configured\n", __func__);
844 return -EINVAL;
845 }
846
847 if (priv->radio_input == XC5000_RADIO_FM1)
848 radio_input = FM_Radio_INPUT1;
849 else if (priv->radio_input == XC5000_RADIO_FM2)
850 radio_input = FM_Radio_INPUT2;
851 else {
852 dprintk(1, "%s() unknown radio input %d\n", __func__,
853 priv->radio_input);
854 return -EINVAL;
855 }
856
857 priv->freq_hz = params->frequency * 125 / 2;
858
859 priv->rf_mode = XC_RF_MODE_AIR;
860
861 ret = xc_SetTVStandard(priv, XC5000_Standard[radio_input].VideoMode,
862 XC5000_Standard[radio_input].AudioMode);
863
864 if (ret != XC_RESULT_SUCCESS) {
865 printk(KERN_ERR "xc5000: xc_SetTVStandard failed\n");
866 return -EREMOTEIO;
867 }
868
869 ret = xc_SetSignalSource(priv, priv->rf_mode);
870 if (ret != XC_RESULT_SUCCESS) {
871 printk(KERN_ERR
872 "xc5000: xc_SetSignalSource(%d) failed\n",
873 priv->rf_mode);
874 return -EREMOTEIO;
875 }
876
877 xc_tune_channel(priv, priv->freq_hz, XC_TUNE_ANALOG);
878
879 return 0;
880}
881
882static int xc5000_set_analog_params(struct dvb_frontend *fe,
883 struct analog_parameters *params)
884{
885 struct xc5000_priv *priv = fe->tuner_priv;
886 int ret = -EINVAL;
887
888 if (priv->i2c_props.adap == NULL)
889 return -EINVAL;
890
891 if (xc5000_is_firmware_loaded(fe) != XC_RESULT_SUCCESS) {
892 if (xc_load_fw_and_init_tuner(fe) != XC_RESULT_SUCCESS) {
893 dprintk(1, "Unable to load firmware and init tuner\n");
894 return -EINVAL;
895 }
896 }
897
898 switch (params->mode) {
899 case V4L2_TUNER_RADIO:
900 ret = xc5000_set_radio_freq(fe, params);
901 break;
902 case V4L2_TUNER_ANALOG_TV:
903 case V4L2_TUNER_DIGITAL_TV:
904 ret = xc5000_set_tv_freq(fe, params);
905 break;
906 }
907
908 return ret;
909}
910
911
830static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq) 912static int xc5000_get_frequency(struct dvb_frontend *fe, u32 *freq)
831{ 913{
832 struct xc5000_priv *priv = fe->tuner_priv; 914 struct xc5000_priv *priv = fe->tuner_priv;
@@ -1000,6 +1082,9 @@ struct dvb_frontend *xc5000_attach(struct dvb_frontend *fe,
1000 priv->if_khz = cfg->if_khz; 1082 priv->if_khz = cfg->if_khz;
1001 } 1083 }
1002 1084
1085 if (priv->radio_input == 0)
1086 priv->radio_input = cfg->radio_input;
1087
1003 /* Check if firmware has been loaded. It is possible that another 1088 /* Check if firmware has been loaded. It is possible that another
1004 instance of the driver has loaded the firmware. 1089 instance of the driver has loaded the firmware.
1005 */ 1090 */
diff --git a/drivers/media/common/tuners/xc5000.h b/drivers/media/common/tuners/xc5000.h
index f4c146698a00..e6d7236c9ea1 100644
--- a/drivers/media/common/tuners/xc5000.h
+++ b/drivers/media/common/tuners/xc5000.h
@@ -30,11 +30,17 @@ struct i2c_adapter;
30struct xc5000_config { 30struct xc5000_config {
31 u8 i2c_address; 31 u8 i2c_address;
32 u32 if_khz; 32 u32 if_khz;
33 u8 radio_input;
33}; 34};
34 35
35/* xc5000 callback command */ 36/* xc5000 callback command */
36#define XC5000_TUNER_RESET 0 37#define XC5000_TUNER_RESET 0
37 38
39/* Possible Radio inputs */
40#define XC5000_RADIO_NOT_CONFIGURED 0
41#define XC5000_RADIO_FM1 1
42#define XC5000_RADIO_FM2 2
43
38/* For each bridge framework, when it attaches either analog or digital, 44/* For each bridge framework, when it attaches either analog or digital,
39 * it has to store a reference back to its _core equivalent structure, 45 * it has to store a reference back to its _core equivalent structure,
40 * so that it can service the hardware by steering gpio's etc. 46 * so that it can service the hardware by steering gpio's etc.