Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[media] saa7134: fix warm Medion 7134 EEPROM read

When saa7134 module driving a Medion 7134 card is reloaded reads of this
card EEPROM (required for automatic detection of tuner model) will be
corrupted due to I2C gate in DVB-T demod being left closed.
This sometimes also happens on first saa7134 module load after a warm
reboot.

Fix this by opening this I2C gate before doing EEPROM read during i2c
initialization.

Signed-off-by: Maciej S. Szmigiero <mail@maciej.szmigiero.name>
Signed-off-by: Mauro Carvalho Chehab <mchehab@s-opensource.com>

authored by

Maciej S. Szmigiero and committed by
Mauro Carvalho Chehab
5a91206f 5fa88151

+31
+31
drivers/media/pci/saa7134/saa7134-i2c.c
··· 355 355 356 356 /* ----------------------------------------------------------- */ 357 357 358 + /* On Medion 7134 reading EEPROM needs DVB-T demod i2c gate open */ 359 + static void saa7134_i2c_eeprom_md7134_gate(struct saa7134_dev *dev) 360 + { 361 + u8 subaddr = 0x7, dmdregval; 362 + u8 data[2]; 363 + int ret; 364 + struct i2c_msg i2cgatemsg_r[] = { {.addr = 0x08, .flags = 0, 365 + .buf = &subaddr, .len = 1}, 366 + {.addr = 0x08, 367 + .flags = I2C_M_RD, 368 + .buf = &dmdregval, .len = 1} 369 + }; 370 + struct i2c_msg i2cgatemsg_w[] = { {.addr = 0x08, .flags = 0, 371 + .buf = data, .len = 2} }; 372 + 373 + ret = i2c_transfer(&dev->i2c_adap, i2cgatemsg_r, 2); 374 + if ((ret == 2) && (dmdregval & 0x2)) { 375 + pr_debug("%s: DVB-T demod i2c gate was left closed\n", 376 + dev->name); 377 + 378 + data[0] = subaddr; 379 + data[1] = (dmdregval & ~0x2); 380 + if (i2c_transfer(&dev->i2c_adap, i2cgatemsg_w, 1) != 1) 381 + pr_err("%s: EEPROM i2c gate open failure\n", 382 + dev->name); 383 + } 384 + } 385 + 358 386 static int 359 387 saa7134_i2c_eeprom(struct saa7134_dev *dev, unsigned char *eedata, int len) 360 388 { 361 389 unsigned char buf; 362 390 int i,err; 391 + 392 + if (dev->board == SAA7134_BOARD_MD7134) 393 + saa7134_i2c_eeprom_md7134_gate(dev); 363 394 364 395 dev->i2c_client.addr = 0xa0 >> 1; 365 396 buf = 0;