aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/saa7134
diff options
context:
space:
mode:
authorKyle Strickland <kyle@kyle.strickland.name>2012-02-18 00:24:53 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2012-03-08 09:01:25 -0500
commit25fa207157102162b1a6abba339dc5fe03f6adc5 (patch)
treed5475f94bd89842c1cb2411c3351de163038fe94 /drivers/media/video/saa7134
parent8d834b526a301d2d10db25835d195edf1141f1a0 (diff)
[media] Add support for KWorld PC150-U ATSC hybrid tuner card
[mchehab@redhat.com: CodingStyle fixes] Signed-off-by: Kyle Strickland <kyle@kyle.strickland.name> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/saa7134')
-rw-r--r--drivers/media/video/saa7134/saa7134-cards.c59
-rw-r--r--drivers/media/video/saa7134/saa7134-dvb.c44
-rw-r--r--drivers/media/video/saa7134/saa7134-i2c.c14
-rw-r--r--drivers/media/video/saa7134/saa7134-input.c63
-rw-r--r--drivers/media/video/saa7134/saa7134.h5
5 files changed, 182 insertions, 3 deletions
diff --git a/drivers/media/video/saa7134/saa7134-cards.c b/drivers/media/video/saa7134/saa7134-cards.c
index 065d0f6be4a0..53aae5968ffb 100644
--- a/drivers/media/video/saa7134/saa7134-cards.c
+++ b/drivers/media/video/saa7134/saa7134-cards.c
@@ -33,6 +33,7 @@
33#include "tea5767.h" 33#include "tea5767.h"
34#include "tda18271.h" 34#include "tda18271.h"
35#include "xc5000.h" 35#include "xc5000.h"
36#include "s5h1411.h"
36 37
37/* commly used strings */ 38/* commly used strings */
38static char name_mute[] = "mute"; 39static char name_mute[] = "mute";
@@ -5712,6 +5713,36 @@ struct saa7134_board saa7134_boards[] = {
5712 .amux = LINE1, 5713 .amux = LINE1,
5713 } }, 5714 } },
5714 }, 5715 },
5716 [SAA7134_BOARD_KWORLD_PC150U] = {
5717 .name = "Kworld PC150-U",
5718 .audio_clock = 0x00187de7,
5719 .tuner_type = TUNER_PHILIPS_TDA8290,
5720 .radio_type = UNSET,
5721 .tuner_addr = ADDR_UNSET,
5722 .radio_addr = ADDR_UNSET,
5723 .mpeg = SAA7134_MPEG_DVB,
5724 .gpiomask = 1 << 21,
5725 .ts_type = SAA7134_MPEG_TS_PARALLEL,
5726 .inputs = { {
5727 .name = name_tv,
5728 .vmux = 1,
5729 .amux = TV,
5730 .tv = 1,
5731 }, {
5732 .name = name_comp,
5733 .vmux = 3,
5734 .amux = LINE1,
5735 }, {
5736 .name = name_svideo,
5737 .vmux = 8,
5738 .amux = LINE2,
5739 } },
5740 .radio = {
5741 .name = name_radio,
5742 .amux = TV,
5743 .gpio = 0x0000000,
5744 },
5745 },
5715 5746
5716}; 5747};
5717 5748
@@ -6306,6 +6337,12 @@ struct pci_device_id saa7134_pci_tbl[] = {
6306 .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */ 6337 .driver_data = SAA7134_BOARD_KWORLD_ATSC110, /* ATSC 115 */
6307 },{ 6338 },{
6308 .vendor = PCI_VENDOR_ID_PHILIPS, 6339 .vendor = PCI_VENDOR_ID_PHILIPS,
6340 .device = PCI_DEVICE_ID_PHILIPS_SAA7133, /* SAA7135HL */
6341 .subvendor = 0x17de,
6342 .subdevice = 0xa134,
6343 .driver_data = SAA7134_BOARD_KWORLD_PC150U,
6344 }, {
6345 .vendor = PCI_VENDOR_ID_PHILIPS,
6309 .device = PCI_DEVICE_ID_PHILIPS_SAA7134, 6346 .device = PCI_DEVICE_ID_PHILIPS_SAA7134,
6310 .subvendor = 0x1461, 6347 .subvendor = 0x1461,
6311 .subdevice = 0x7360, 6348 .subdevice = 0x7360,
@@ -7134,6 +7171,23 @@ static inline int saa7134_kworld_sbtvd_toggle_agc(struct saa7134_dev *dev,
7134 return 0; 7171 return 0;
7135} 7172}
7136 7173
7174static int saa7134_kworld_pc150u_toggle_agc(struct saa7134_dev *dev,
7175 enum tda18271_mode mode)
7176{
7177 switch (mode) {
7178 case TDA18271_ANALOG:
7179 saa7134_set_gpio(dev, 18, 0);
7180 break;
7181 case TDA18271_DIGITAL:
7182 saa7134_set_gpio(dev, 18, 1);
7183 msleep(30);
7184 break;
7185 default:
7186 return -EINVAL;
7187 }
7188 return 0;
7189}
7190
7137static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev, 7191static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
7138 int command, int arg) 7192 int command, int arg)
7139{ 7193{
@@ -7150,6 +7204,9 @@ static int saa7134_tda8290_18271_callback(struct saa7134_dev *dev,
7150 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7204 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
7151 ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg); 7205 ret = saa7134_kworld_sbtvd_toggle_agc(dev, arg);
7152 break; 7206 break;
7207 case SAA7134_BOARD_KWORLD_PC150U:
7208 ret = saa7134_kworld_pc150u_toggle_agc(dev, arg);
7209 break;
7153 default: 7210 default:
7154 break; 7211 break;
7155 } 7212 }
@@ -7171,6 +7228,7 @@ static int saa7134_tda8290_callback(struct saa7134_dev *dev,
7171 case SAA7134_BOARD_HAUPPAUGE_HVR1120: 7228 case SAA7134_BOARD_HAUPPAUGE_HVR1120:
7172 case SAA7134_BOARD_AVERMEDIA_M733A: 7229 case SAA7134_BOARD_AVERMEDIA_M733A:
7173 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG: 7230 case SAA7134_BOARD_KWORLD_PCI_SBTVD_FULLSEG:
7231 case SAA7134_BOARD_KWORLD_PC150U:
7174 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2: 7232 case SAA7134_BOARD_MAGICPRO_PROHDTV_PRO2:
7175 /* tda8290 + tda18271 */ 7233 /* tda8290 + tda18271 */
7176 ret = saa7134_tda8290_18271_callback(dev, command, arg); 7234 ret = saa7134_tda8290_18271_callback(dev, command, arg);
@@ -7452,6 +7510,7 @@ int saa7134_board_init1(struct saa7134_dev *dev)
7452 case SAA7134_BOARD_BEHOLD_X7: 7510 case SAA7134_BOARD_BEHOLD_X7:
7453 case SAA7134_BOARD_BEHOLD_H7: 7511 case SAA7134_BOARD_BEHOLD_H7:
7454 case SAA7134_BOARD_BEHOLD_A7: 7512 case SAA7134_BOARD_BEHOLD_A7:
7513 case SAA7134_BOARD_KWORLD_PC150U:
7455 dev->has_remote = SAA7134_REMOTE_I2C; 7514 dev->has_remote = SAA7134_REMOTE_I2C;
7456 break; 7515 break;
7457 case SAA7134_BOARD_AVERMEDIA_A169_B: 7516 case SAA7134_BOARD_AVERMEDIA_A169_B:
diff --git a/drivers/media/video/saa7134/saa7134-dvb.c b/drivers/media/video/saa7134/saa7134-dvb.c
index 089fa0fb5c94..aaa5c97a7216 100644
--- a/drivers/media/video/saa7134/saa7134-dvb.c
+++ b/drivers/media/video/saa7134/saa7134-dvb.c
@@ -61,6 +61,7 @@
61#include "zl10036.h" 61#include "zl10036.h"
62#include "zl10039.h" 62#include "zl10039.h"
63#include "mt312.h" 63#include "mt312.h"
64#include "s5h1411.h"
64 65
65MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]"); 66MODULE_AUTHOR("Gerd Knorr <kraxel@bytesex.org> [SuSE Labs]");
66MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
@@ -1158,6 +1159,33 @@ static struct tda18271_config prohdtv_pro2_tda18271_config = {
1158 .output_opt = TDA18271_OUTPUT_LT_OFF, 1159 .output_opt = TDA18271_OUTPUT_LT_OFF,
1159}; 1160};
1160 1161
1162static struct tda18271_std_map kworld_tda18271_std_map = {
1163 .atsc_6 = { .if_freq = 3250, .agc_mode = 3, .std = 3,
1164 .if_lvl = 6, .rfagc_top = 0x37 },
1165 .qam_6 = { .if_freq = 4000, .agc_mode = 3, .std = 0,
1166 .if_lvl = 6, .rfagc_top = 0x37 },
1167};
1168
1169static struct tda18271_config kworld_pc150u_tda18271_config = {
1170 .std_map = &kworld_tda18271_std_map,
1171 .gate = TDA18271_GATE_ANALOG,
1172 .output_opt = TDA18271_OUTPUT_LT_OFF,
1173 .config = 3, /* Use tuner callback for AGC */
1174 .rf_cal_on_startup = 1
1175};
1176
1177static struct s5h1411_config kworld_s5h1411_config = {
1178 .output_mode = S5H1411_PARALLEL_OUTPUT,
1179 .gpio = S5H1411_GPIO_OFF,
1180 .qam_if = S5H1411_IF_4000,
1181 .vsb_if = S5H1411_IF_3250,
1182 .inversion = S5H1411_INVERSION_ON,
1183 .status_mode = S5H1411_DEMODLOCKING,
1184 .mpeg_timing =
1185 S5H1411_MPEGTIMING_CONTINOUS_NONINVERTING_CLOCK,
1186};
1187
1188
1161/* ================================================================== 1189/* ==================================================================
1162 * Core code 1190 * Core code
1163 */ 1191 */
@@ -1438,6 +1466,22 @@ static int dvb_init(struct saa7134_dev *dev)
1438 &dev->i2c_adap, 0x61, 1466 &dev->i2c_adap, 0x61,
1439 TUNER_PHILIPS_TUV1236D); 1467 TUNER_PHILIPS_TUV1236D);
1440 break; 1468 break;
1469 case SAA7134_BOARD_KWORLD_PC150U:
1470 saa7134_set_gpio(dev, 18, 1); /* Switch to digital mode */
1471 saa7134_tuner_callback(dev, 0,
1472 TDA18271_CALLBACK_CMD_AGC_ENABLE, 1);
1473 fe0->dvb.frontend = dvb_attach(s5h1411_attach,
1474 &kworld_s5h1411_config,
1475 &dev->i2c_adap);
1476 if (fe0->dvb.frontend != NULL) {
1477 dvb_attach(tda829x_attach, fe0->dvb.frontend,
1478 &dev->i2c_adap, 0x4b,
1479 &tda829x_no_probe);
1480 dvb_attach(tda18271_attach, fe0->dvb.frontend,
1481 0x60, &dev->i2c_adap,
1482 &kworld_pc150u_tda18271_config);
1483 }
1484 break;
1441 case SAA7134_BOARD_FLYDVBS_LR300: 1485 case SAA7134_BOARD_FLYDVBS_LR300:
1442 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs, 1486 fe0->dvb.frontend = dvb_attach(tda10086_attach, &flydvbs,
1443 &dev->i2c_adap); 1487 &dev->i2c_adap);
diff --git a/drivers/media/video/saa7134/saa7134-i2c.c b/drivers/media/video/saa7134/saa7134-i2c.c
index 2d3f6d265bbf..a176ec3285e0 100644
--- a/drivers/media/video/saa7134/saa7134-i2c.c
+++ b/drivers/media/video/saa7134/saa7134-i2c.c
@@ -254,7 +254,9 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
254 addr = msgs[i].addr << 1; 254 addr = msgs[i].addr << 1;
255 if (msgs[i].flags & I2C_M_RD) 255 if (msgs[i].flags & I2C_M_RD)
256 addr |= 1; 256 addr |= 1;
257 if (i > 0 && msgs[i].flags & I2C_M_RD && msgs[i].addr != 0x40) { 257 if (i > 0 && msgs[i].flags &
258 I2C_M_RD && msgs[i].addr != 0x40 &&
259 msgs[i].addr != 0x19) {
258 /* workaround for a saa7134 i2c bug 260 /* workaround for a saa7134 i2c bug
259 * needed to talk to the mt352 demux 261 * needed to talk to the mt352 demux
260 * thanks to pinnacle for the hint */ 262 * thanks to pinnacle for the hint */
@@ -279,6 +281,16 @@ static int saa7134_i2c_xfer(struct i2c_adapter *i2c_adap,
279 d1printk("%02x", rc); 281 d1printk("%02x", rc);
280 msgs[i].buf[byte] = rc; 282 msgs[i].buf[byte] = rc;
281 } 283 }
284 /* discard mysterious extra byte when reading
285 from Samsung S5H1411. i2c bus gets error
286 if we do not. */
287 if (0x19 == msgs[i].addr) {
288 d1printk(" ?");
289 rc = i2c_recv_byte(dev);
290 if (rc < 0)
291 goto err;
292 d1printk("%02x", rc);
293 }
282 } else { 294 } else {
283 /* write bytes */ 295 /* write bytes */
284 d2printk("write bytes\n"); 296 d2printk("write bytes\n");
diff --git a/drivers/media/video/saa7134/saa7134-input.c b/drivers/media/video/saa7134/saa7134-input.c
index 22ecd7297d2d..48d2878699b7 100644
--- a/drivers/media/video/saa7134/saa7134-input.c
+++ b/drivers/media/video/saa7134/saa7134-input.c
@@ -210,6 +210,54 @@ static int get_key_msi_tvanywhere_plus(struct IR_i2c *ir, u32 *ir_key,
210 return 1; 210 return 1;
211} 211}
212 212
213/* copied and modified from get_key_msi_tvanywhere_plus() */
214static int get_key_kworld_pc150u(struct IR_i2c *ir, u32 *ir_key,
215 u32 *ir_raw)
216{
217 unsigned char b;
218 unsigned int gpio;
219
220 /* <dev> is needed to access GPIO. Used by the saa_readl macro. */
221 struct saa7134_dev *dev = ir->c->adapter->algo_data;
222 if (dev == NULL) {
223 i2cdprintk("get_key_kworld_pc150u: "
224 "ir->c->adapter->algo_data is NULL!\n");
225 return -EIO;
226 }
227
228 /* rising SAA7134_GPIO_GPRESCAN reads the status */
229
230 saa_clearb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
231 saa_setb(SAA7134_GPIO_GPMODE3, SAA7134_GPIO_GPRESCAN);
232
233 gpio = saa_readl(SAA7134_GPIO_GPSTATUS0 >> 2);
234
235 /* GPIO&0x100 is pulsed low when a button is pressed. Don't do
236 I2C receive if gpio&0x100 is not low. */
237
238 if (gpio & 0x100)
239 return 0; /* No button press */
240
241 /* GPIO says there is a button press. Get it. */
242
243 if (1 != i2c_master_recv(ir->c, &b, 1)) {
244 i2cdprintk("read error\n");
245 return -EIO;
246 }
247
248 /* No button press */
249
250 if (b == 0xff)
251 return 0;
252
253 /* Button pressed */
254
255 dprintk("get_key_kworld_pc150u: Key = 0x%02X\n", b);
256 *ir_key = b;
257 *ir_raw = b;
258 return 1;
259}
260
213static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw) 261static int get_key_purpletv(struct IR_i2c *ir, u32 *ir_key, u32 *ir_raw)
214{ 262{
215 unsigned char b; 263 unsigned char b;
@@ -901,6 +949,21 @@ void saa7134_probe_i2c_ir(struct saa7134_dev *dev)
901 msg_msi.addr, dev->i2c_adap.name, 949 msg_msi.addr, dev->i2c_adap.name,
902 (1 == rc) ? "yes" : "no"); 950 (1 == rc) ? "yes" : "no");
903 break; 951 break;
952 case SAA7134_BOARD_KWORLD_PC150U:
953 /* copied and modified from MSI TV@nywhere Plus */
954 dev->init_data.name = "Kworld PC150-U";
955 dev->init_data.get_key = get_key_kworld_pc150u;
956 dev->init_data.ir_codes = RC_MAP_KWORLD_PC150U;
957 info.addr = 0x30;
958 /* MSI TV@nywhere Plus controller doesn't seem to
959 respond to probes unless we read something from
960 an existing device. Weird...
961 REVISIT: might no longer be needed */
962 rc = i2c_transfer(&dev->i2c_adap, &msg_msi, 1);
963 dprintk("probe 0x%02x @ %s: %s\n",
964 msg_msi.addr, dev->i2c_adap.name,
965 (1 == rc) ? "yes" : "no");
966 break;
904 case SAA7134_BOARD_HAUPPAUGE_HVR1110: 967 case SAA7134_BOARD_HAUPPAUGE_HVR1110:
905 dev->init_data.name = "HVR 1110"; 968 dev->init_data.name = "HVR 1110";
906 dev->init_data.get_key = get_key_hvr1110; 969 dev->init_data.get_key = get_key_hvr1110;
diff --git a/drivers/media/video/saa7134/saa7134.h b/drivers/media/video/saa7134/saa7134.h
index 42fba4f93c72..f625060e6a0f 100644
--- a/drivers/media/video/saa7134/saa7134.h
+++ b/drivers/media/video/saa7134/saa7134.h
@@ -126,8 +126,8 @@ struct saa7134_card_ir {
126 unsigned users; 126 unsigned users;
127 127
128 u32 polling; 128 u32 polling;
129 u32 last_gpio; 129 u32 last_gpio;
130 u32 mask_keycode, mask_keydown, mask_keyup; 130 u32 mask_keycode, mask_keydown, mask_keyup;
131 131
132 bool running; 132 bool running;
133 bool active; 133 bool active;
@@ -331,6 +331,7 @@ struct saa7134_card_ir {
331#define SAA7134_BOARD_BEHOLD_501 186 331#define SAA7134_BOARD_BEHOLD_501 186
332#define SAA7134_BOARD_BEHOLD_503FM 187 332#define SAA7134_BOARD_BEHOLD_503FM 187
333#define SAA7134_BOARD_SENSORAY811_911 188 333#define SAA7134_BOARD_SENSORAY811_911 188
334#define SAA7134_BOARD_KWORLD_PC150U 189
334 335
335#define SAA7134_MAXBOARDS 32 336#define SAA7134_MAXBOARDS 32
336#define SAA7134_INPUT_MAX 8 337#define SAA7134_INPUT_MAX 8