aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Isely <isely@pobox.com>2009-03-06 21:42:20 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2009-03-30 11:43:33 -0400
commite9c64a78dbd7c4f6c4a31c4040f340f732bf4ec5 (patch)
treeb8bdf899e92f241d4b7581276b62461a968f3f76
parentacd92d40ccaf140d27e6bd5b83573294165ebbdf (diff)
V4L/DVB (11158): pvrusb2: New device attribute mechanism to specify sub-devices
Set up new mechanism for declaring and loading appropriate sub-devices when driver initializes. This is another part of the v4l2-subdev adoption. Signed-off-by: Mike Isely <isely@pobox.com> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-devattr.h28
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-hdw.c119
-rw-r--r--drivers/media/video/pvrusb2/pvrusb2-i2c-core.c1
3 files changed, 144 insertions, 4 deletions
diff --git a/drivers/media/video/pvrusb2/pvrusb2-devattr.h b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
index cb3a33eb0276..f06923986824 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-devattr.h
+++ b/drivers/media/video/pvrusb2/pvrusb2-devattr.h
@@ -33,6 +33,31 @@
33*/ 33*/
34 34
35 35
36#define PVR2_CLIENT_ID_MSP3400 1
37#define PVR2_CLIENT_ID_CX25840 2
38#define PVR2_CLIENT_ID_SAA7115 3
39#define PVR2_CLIENT_ID_TUNER 4
40#define PVR2_CLIENT_ID_CS53132A 5
41
42struct pvr2_device_client_desc {
43 /* One ovr PVR2_CLIENT_ID_xxxx */
44 unsigned char module_id;
45
46 /* Null-terminated array of I2C addresses to try in order
47 initialize the module. It's safe to make this null terminated
48 since we're never going to encounter an i2c device with an
49 address of zero. If this is a null pointer or zero-length,
50 then no I2C addresses have been specified, in which case we'll
51 try some compiled in defaults for now. */
52 unsigned char *i2c_address_list;
53};
54
55struct pvr2_device_client_table {
56 const struct pvr2_device_client_desc *lst;
57 unsigned char cnt;
58};
59
60
36struct pvr2_string_table { 61struct pvr2_string_table {
37 const char **lst; 62 const char **lst;
38 unsigned int cnt; 63 unsigned int cnt;
@@ -66,6 +91,9 @@ struct pvr2_device_desc {
66 /* List of additional client modules we need to load */ 91 /* List of additional client modules we need to load */
67 struct pvr2_string_table client_modules; 92 struct pvr2_string_table client_modules;
68 93
94 /* List of defined client modules we need to load */
95 struct pvr2_device_client_table client_table;
96
69 /* List of FX2 firmware file names we should search; if empty then 97 /* List of FX2 firmware file names we should search; if empty then
70 FX2 firmware check / load is skipped and we assume the device 98 FX2 firmware check / load is skipped and we assume the device
71 was initialized from internal ROM. */ 99 was initialized from internal ROM. */
diff --git a/drivers/media/video/pvrusb2/pvrusb2-hdw.c b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
index e6c4660786a6..faa94cef2c55 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-hdw.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-hdw.c
@@ -105,6 +105,20 @@ MODULE_PARM_DESC(radio_freq, "specify initial radio frequency");
105/* size of a firmware chunk */ 105/* size of a firmware chunk */
106#define FIRMWARE_CHUNK_SIZE 0x2000 106#define FIRMWARE_CHUNK_SIZE 0x2000
107 107
108static const char *module_names[] = {
109 [PVR2_CLIENT_ID_MSP3400] = "msp3400",
110 [PVR2_CLIENT_ID_CX25840] = "cx25840",
111 [PVR2_CLIENT_ID_SAA7115] = "saa7115",
112 [PVR2_CLIENT_ID_TUNER] = "tuner",
113 [PVR2_CLIENT_ID_CS53132A] = "cs53132a",
114};
115
116
117static const unsigned char *module_i2c_addresses[] = {
118 [PVR2_CLIENT_ID_TUNER] = "\x60\x61\x62\x63",
119};
120
121
108/* Define the list of additional controls we'll dynamically construct based 122/* Define the list of additional controls we'll dynamically construct based
109 on query of the cx2341x module. */ 123 on query of the cx2341x module. */
110struct pvr2_mpeg_ids { 124struct pvr2_mpeg_ids {
@@ -1934,6 +1948,105 @@ static void pvr2_hdw_setup_std(struct pvr2_hdw *hdw)
1934} 1948}
1935 1949
1936 1950
1951static unsigned int pvr2_copy_i2c_addr_list(
1952 unsigned short *dst, const unsigned char *src,
1953 unsigned int dst_max)
1954{
1955 unsigned int cnt;
1956 if (!src) return 0;
1957 while (src[cnt] && (cnt + 1) < dst_max) {
1958 dst[cnt] = src[cnt];
1959 cnt++;
1960 }
1961 dst[cnt] = I2C_CLIENT_END;
1962 return cnt;
1963}
1964
1965
1966static void pvr2_hdw_load_subdev(struct pvr2_hdw *hdw,
1967 const struct pvr2_device_client_desc *cd)
1968{
1969 const char *fname;
1970 unsigned char mid;
1971 struct v4l2_subdev *sd;
1972 unsigned int i2ccnt;
1973 const unsigned char *p;
1974 /* Arbitrary count - max # i2c addresses we will probe */
1975 unsigned short i2caddr[25];
1976
1977 mid = cd->module_id;
1978 fname = (mid < ARRAY_SIZE(module_names)) ? module_names[mid] : NULL;
1979 if (!fname) {
1980 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1981 "Module ID %u for device %s is unknown"
1982 " (this is probably a bad thing...)",
1983 mid,
1984 hdw->hdw_desc->description);
1985 return;
1986 }
1987
1988 i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, cd->i2c_address_list,
1989 ARRAY_SIZE(i2caddr));
1990 if (!i2ccnt && ((p = (mid < ARRAY_SIZE(module_i2c_addresses)) ?
1991 module_i2c_addresses[mid] : NULL) != NULL)) {
1992 /* Second chance: Try default i2c address list */
1993 i2ccnt = pvr2_copy_i2c_addr_list(i2caddr, p,
1994 ARRAY_SIZE(i2caddr));
1995 }
1996
1997 if (!i2ccnt) {
1998 pvr2_trace(PVR2_TRACE_ERROR_LEGS,
1999 "Module ID %u for device %s:"
2000 " No i2c addresses"
2001 " (this is probably a bad thing...)",
2002 mid, hdw->hdw_desc->description);
2003 return;
2004 }
2005
2006 /* Note how the 2nd and 3rd arguments are the same for both
2007 * v4l2_i2c_new_subdev() and v4l2_i2c_new_probed_subdev(). Why?
2008 * Well the 2nd argument is the module name to load, while the 3rd
2009 * argument is documented in the framework as being the "chipid" -
2010 * and every other place where I can find examples of this, the
2011 * "chipid" appears to just be the module name again. So here we
2012 * just do the same thing. */
2013 if (i2ccnt == 1) {
2014 sd = v4l2_i2c_new_subdev(&hdw->i2c_adap,
2015 fname, fname,
2016 i2caddr[0]);
2017 } else {
2018 sd = v4l2_i2c_new_probed_subdev(&hdw->i2c_adap,
2019 fname, fname,
2020 i2caddr);
2021 }
2022
2023 // ?????
2024 /* Based on module ID, we should remember subdev pointers
2025 so that we can send certain custom commands where
2026 needed. */
2027 // ?????
2028
2029}
2030
2031
2032static void pvr2_hdw_load_modules(struct pvr2_hdw *hdw)
2033{
2034 unsigned int idx;
2035 const struct pvr2_string_table *cm;
2036 const struct pvr2_device_client_table *ct;
2037
2038 cm = &hdw->hdw_desc->client_modules;
2039 for (idx = 0; idx < cm->cnt; idx++) {
2040 request_module(cm->lst[idx]);
2041 }
2042
2043 ct = &hdw->hdw_desc->client_table;
2044 for (idx = 0; idx < ct->cnt; idx++) {
2045 pvr2_hdw_load_subdev(hdw,&ct->lst[idx]);
2046 }
2047}
2048
2049
1937static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw) 2050static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1938{ 2051{
1939 int ret; 2052 int ret;
@@ -1973,10 +2086,6 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1973 2086
1974 if (!pvr2_hdw_dev_ok(hdw)) return; 2087 if (!pvr2_hdw_dev_ok(hdw)) return;
1975 2088
1976 for (idx = 0; idx < hdw->hdw_desc->client_modules.cnt; idx++) {
1977 request_module(hdw->hdw_desc->client_modules.lst[idx]);
1978 }
1979
1980 if (!hdw->hdw_desc->flag_no_powerup) { 2089 if (!hdw->hdw_desc->flag_no_powerup) {
1981 pvr2_hdw_cmd_powerup(hdw); 2090 pvr2_hdw_cmd_powerup(hdw);
1982 if (!pvr2_hdw_dev_ok(hdw)) return; 2091 if (!pvr2_hdw_dev_ok(hdw)) return;
@@ -1995,6 +2104,8 @@ static void pvr2_hdw_setup_low(struct pvr2_hdw *hdw)
1995 pvr2_i2c_core_init(hdw); 2104 pvr2_i2c_core_init(hdw);
1996 if (!pvr2_hdw_dev_ok(hdw)) return; 2105 if (!pvr2_hdw_dev_ok(hdw)) return;
1997 2106
2107 pvr2_hdw_load_modules(hdw);
2108
1998 for (idx = 0; idx < CTRLDEF_COUNT; idx++) { 2109 for (idx = 0; idx < CTRLDEF_COUNT; idx++) {
1999 cptr = hdw->controls + idx; 2110 cptr = hdw->controls + idx;
2000 if (cptr->info->skip_init) continue; 2111 if (cptr->info->skip_init) continue;
diff --git a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
index 2ba429f1bc8e..1129fe40c04c 100644
--- a/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
+++ b/drivers/media/video/pvrusb2/pvrusb2-i2c-core.c
@@ -608,6 +608,7 @@ void pvr2_i2c_core_init(struct pvr2_hdw *hdw)
608 hdw->i2c_adap.algo = &hdw->i2c_algo; 608 hdw->i2c_adap.algo = &hdw->i2c_algo;
609 hdw->i2c_adap.algo_data = hdw; 609 hdw->i2c_adap.algo_data = hdw;
610 hdw->i2c_linked = !0; 610 hdw->i2c_linked = !0;
611 i2c_set_adapdata(&hdw->i2c_adap, &hdw->v4l2_dev);
611 i2c_add_adapter(&hdw->i2c_adap); 612 i2c_add_adapter(&hdw->i2c_adap);
612 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) { 613 if (hdw->i2c_func[0x18] == i2c_24xxx_ir) {
613 /* Probe for a different type of IR receiver on this 614 /* Probe for a different type of IR receiver on this