From: Steven Toth Date: Sun, 27 Sep 2009 18:54:47 +0000 (-0300) Subject: V4L/DVB (13092): cx25840: Improvements to the cx23885/7/8 chip detection mechanism. X-Git-Tag: firefly_0821_release~9833^2~3918^2~302 X-Git-Url: http://demsky.eecs.uci.edu/git/?a=commitdiff_plain;h=8c2d7821d4e3827c29e4e4e345ee25390a141e55;p=firefly-linux-kernel-4.4.55.git V4L/DVB (13092): cx25840: Improvements to the cx23885/7/8 chip detection mechanism. The prior mechanism wasn't reliable with the cx23887. This new mechanism tests correctly against cx23885, 7 and 8 based products. Signed-off-by: Steven Toth Signed-off-by: Mauro Carvalho Chehab --- diff --git a/drivers/media/video/cx25840/cx25840-core.c b/drivers/media/video/cx25840/cx25840-core.c index 56ead3d37926..904e9a5a9065 100644 --- a/drivers/media/video/cx25840/cx25840-core.c +++ b/drivers/media/video/cx25840/cx25840-core.c @@ -1598,14 +1598,29 @@ static u32 get_cx2388x_ident(struct i2c_client *client) /* Come out of digital power down */ cx25840_write(client, 0x000, 0); + /* Detecting whether the part is cx23885/7/8 is more + * difficult than it needs to be. No ID register. Instead we + * probe certain registers indicated in the datasheets to look + * for specific defaults that differ between the silicon designs. */ + + /* It's either 885/7 if the IR Tx Clk Divider register exists */ if (cx25840_read4(client, 0x204) & 0xffff) { - /* IR Tx Clk Divider register exists; chip must be a CX23885 */ - ret = V4L2_IDENT_CX23885_AV; + /* CX23885 returns bogus repetitive byte values for the DIF, + * which doesn't exist for it. (Ex. 8a8a8a8a or 31313131) */ + ret = cx25840_read4(client, 0x300); + if (((ret & 0xffff0000) >> 16) == (ret & 0xffff)) { + /* No DIF */ + ret = V4L2_IDENT_CX23885_AV; + } else { + /* CX23887 has a broken DIF, but the registers + * appear valid (but unsed), good enough to detect. */ + ret = V4L2_IDENT_CX23887_AV; + } } else if (cx25840_read4(client, 0x300) & 0x0fffffff) { /* DIF PLL Freq Word reg exists; chip must be a CX23888 */ ret = V4L2_IDENT_CX23888_AV; } else { - /* A CX23887 A/V core has neither IR nor DIF */ + v4l_err(client, "Unable to detect h/w, assuming cx23887\n"); ret = V4L2_IDENT_CX23887_AV; }