aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/tuner-core.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2007-11-04 09:03:36 -0500
committerMauro Carvalho Chehab <mchehab@infradead.org>2008-01-25 16:02:00 -0500
commit9dd659de9fbd1687c6175053c6453db5b932f152 (patch)
tree5e07d228f4eaff3ae66bb96fd56792463adcc261 /drivers/media/video/tuner-core.c
parent92de1f16d15a30831d1685949aeb76c99032ef23 (diff)
V4L/DVB (6556): tuner: convert to bus-based I2C API
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@infradead.org>
Diffstat (limited to 'drivers/media/video/tuner-core.c')
-rw-r--r--drivers/media/video/tuner-core.c99
1 files changed, 32 insertions, 67 deletions
diff --git a/drivers/media/video/tuner-core.c b/drivers/media/video/tuner-core.c
index 48b2d46048ab..1b0d28a0ca78 100644
--- a/drivers/media/video/tuner-core.c
+++ b/drivers/media/video/tuner-core.c
@@ -19,6 +19,7 @@
19#include <media/tuner.h> 19#include <media/tuner.h>
20#include <media/tuner-types.h> 20#include <media/tuner-types.h>
21#include <media/v4l2-common.h> 21#include <media/v4l2-common.h>
22#include <media/v4l2-i2c-drv-legacy.h>
22#include "tuner-driver.h" 23#include "tuner-driver.h"
23#include "mt20xx.h" 24#include "mt20xx.h"
24#include "tda8290.h" 25#include "tda8290.h"
@@ -30,7 +31,7 @@
30 31
31#define UNSET (-1U) 32#define UNSET (-1U)
32 33
33#define PREFIX "tuner " 34#define PREFIX t->i2c->driver->driver.name
34 35
35/* standard i2c insmod options */ 36/* standard i2c insmod options */
36static unsigned short normal_i2c[] = { 37static unsigned short normal_i2c[] = {
@@ -75,9 +76,6 @@ MODULE_DESCRIPTION("device driver for various TV and TV+FM radio tuners");
75MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer"); 76MODULE_AUTHOR("Ralph Metzler, Gerd Knorr, Gunther Mayer");
76MODULE_LICENSE("GPL"); 77MODULE_LICENSE("GPL");
77 78
78static struct i2c_driver driver;
79static struct i2c_client client_template;
80
81/* ---------------------------------------------------------------------- */ 79/* ---------------------------------------------------------------------- */
82 80
83static void fe_set_freq(struct dvb_frontend *fe, unsigned int freq) 81static void fe_set_freq(struct dvb_frontend *fe, unsigned int freq)
@@ -919,18 +917,18 @@ static int tuner_command(struct i2c_client *client, unsigned int cmd, void *arg)
919 917
920static int tuner_suspend(struct i2c_client *c, pm_message_t state) 918static int tuner_suspend(struct i2c_client *c, pm_message_t state)
921{ 919{
922 struct tuner *t = i2c_get_clientdata (c); 920 struct tuner *t = i2c_get_clientdata(c);
923 921
924 tuner_dbg ("suspend\n"); 922 tuner_dbg("suspend\n");
925 /* FIXME: power down ??? */ 923 /* FIXME: power down ??? */
926 return 0; 924 return 0;
927} 925}
928 926
929static int tuner_resume(struct i2c_client *c) 927static int tuner_resume(struct i2c_client *c)
930{ 928{
931 struct tuner *t = i2c_get_clientdata (c); 929 struct tuner *t = i2c_get_clientdata(c);
932 930
933 tuner_dbg ("resume\n"); 931 tuner_dbg("resume\n");
934 if (V4L2_TUNER_RADIO == t->mode) { 932 if (V4L2_TUNER_RADIO == t->mode) {
935 if (t->radio_freq) 933 if (t->radio_freq)
936 set_freq(c, t->radio_freq); 934 set_freq(c, t->radio_freq);
@@ -946,7 +944,7 @@ static int tuner_resume(struct i2c_client *c)
946LIST_HEAD(tuner_list); 944LIST_HEAD(tuner_list);
947 945
948/* Search for existing radio and/or TV tuners on the given I2C adapter. 946/* Search for existing radio and/or TV tuners on the given I2C adapter.
949 Note that when this function is called from tuner_attach you can be 947 Note that when this function is called from tuner_probe you can be
950 certain no other devices will be added/deleted at the same time, I2C 948 certain no other devices will be added/deleted at the same time, I2C
951 core protects against that. */ 949 core protects against that. */
952static void tuner_lookup(struct i2c_adapter *adap, 950static void tuner_lookup(struct i2c_adapter *adap,
@@ -977,28 +975,19 @@ static void tuner_lookup(struct i2c_adapter *adap,
977} 975}
978 976
979/* During client attach, set_type is called by adapter's attach_inform callback. 977/* During client attach, set_type is called by adapter's attach_inform callback.
980 set_type must then be completed by tuner_attach. 978 set_type must then be completed by tuner_probe.
981 */ 979 */
982static int tuner_attach(struct i2c_adapter *adap, int addr, int kind) 980static int tuner_probe(struct i2c_client *client)
983{ 981{
984 struct i2c_client *client;
985 struct tuner *t; 982 struct tuner *t;
986 struct tuner *radio; 983 struct tuner *radio;
987 struct tuner *tv; 984 struct tuner *tv;
988 985
989 client = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
990 if (NULL == client)
991 return -ENOMEM;
992
993 t = kzalloc(sizeof(struct tuner), GFP_KERNEL); 986 t = kzalloc(sizeof(struct tuner), GFP_KERNEL);
994 if (NULL == t) { 987 if (NULL == t)
995 kfree(client);
996 return -ENOMEM; 988 return -ENOMEM;
997 }
998 t->i2c = client; 989 t->i2c = client;
999 client_template.adapter = adap; 990 strlcpy(client->name, "(tuner unset)", sizeof(client->name));
1000 client_template.addr = addr;
1001 memcpy(client, &client_template, sizeof(struct i2c_client));
1002 i2c_set_clientdata(client, t); 991 i2c_set_clientdata(client, t);
1003 t->type = UNSET; 992 t->type = UNSET;
1004 t->audmode = V4L2_TUNER_MODE_STEREO; 993 t->audmode = V4L2_TUNER_MODE_STEREO;
@@ -1015,14 +1004,16 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
1015 printk(KERN_CONT "%02x ", buffer[i]); 1004 printk(KERN_CONT "%02x ", buffer[i]);
1016 printk("\n"); 1005 printk("\n");
1017 } 1006 }
1018 /* HACK: This test were added to avoid tuner to probe tda9840 and 1007 /* HACK: This test was added to avoid tuner to probe tda9840 and
1019 tea6415c on the MXB card */ 1008 tea6415c on the MXB card */
1020 if (adap->id == I2C_HW_SAA7146 && addr < 0x4a) 1009 if (client->adapter->id == I2C_HW_SAA7146 && client->addr < 0x4a) {
1010 kfree(t);
1021 return -ENODEV; 1011 return -ENODEV;
1012 }
1022 1013
1023 /* autodetection code based on the i2c addr */ 1014 /* autodetection code based on the i2c addr */
1024 if (!no_autodetect) { 1015 if (!no_autodetect) {
1025 switch (addr) { 1016 switch (client->addr) {
1026 case 0x10: 1017 case 0x10:
1027 if (tea5761_autodetection(t->i2c->adapter, t->i2c->addr) 1018 if (tea5761_autodetection(t->i2c->adapter, t->i2c->addr)
1028 != EINVAL) { 1019 != EINVAL) {
@@ -1092,7 +1083,8 @@ static int tuner_attach(struct i2c_adapter *adap, int addr, int kind)
1092 1083
1093 /* Should be just before return */ 1084 /* Should be just before return */
1094register_client: 1085register_client:
1095 tuner_info("chip found @ 0x%x (%s)\n", addr << 1, adap->name); 1086 tuner_info("chip found @ 0x%x (%s)\n", client->addr << 1,
1087 client->adapter->name);
1096 1088
1097 /* Sets a default mode */ 1089 /* Sets a default mode */
1098 if (t->mode_mask & T_ANALOG_TV) { 1090 if (t->mode_mask & T_ANALOG_TV) {
@@ -1102,19 +1094,21 @@ register_client:
1102 } else { 1094 } else {
1103 t->mode = T_DIGITAL_TV; 1095 t->mode = T_DIGITAL_TV;
1104 } 1096 }
1105
1106 i2c_attach_client(client);
1107 set_type(client, t->type, t->mode_mask, t->config, t->tuner_callback); 1097 set_type(client, t->type, t->mode_mask, t->config, t->tuner_callback);
1098 list_add_tail(&t->list, &tuner_list);
1108 return 0; 1099 return 0;
1109} 1100}
1110 1101
1111static int tuner_probe(struct i2c_adapter *adap) 1102static int tuner_legacy_probe(struct i2c_adapter *adap)
1112{ 1103{
1113 if (0 != addr) { 1104 if (0 != addr) {
1114 normal_i2c[0] = addr; 1105 normal_i2c[0] = addr;
1115 normal_i2c[1] = I2C_CLIENT_END; 1106 normal_i2c[1] = I2C_CLIENT_END;
1116 } 1107 }
1117 1108
1109 if ((adap->class & I2C_CLASS_TV_ANALOG) == 0)
1110 return 0;
1111
1118 /* HACK: Ignore 0x6b and 0x6f on cx88 boards. 1112 /* HACK: Ignore 0x6b and 0x6f on cx88 boards.
1119 * FusionHDTV5 RT Gold has an ir receiver at 0x6b 1113 * FusionHDTV5 RT Gold has an ir receiver at 0x6b
1120 * and an RTC at 0x6f which can get corrupted if probed. 1114 * and an RTC at 0x6f which can get corrupted if probed.
@@ -1136,64 +1130,35 @@ static int tuner_probe(struct i2c_adapter *adap)
1136 "too many options specified " 1130 "too many options specified "
1137 "in i2c probe ignore list!\n"); 1131 "in i2c probe ignore list!\n");
1138 } 1132 }
1139 1133 return 1;
1140 if (adap->class & I2C_CLASS_TV_ANALOG)
1141 return i2c_probe(adap, &addr_data, tuner_attach);
1142 return 0;
1143} 1134}
1144 1135
1145static int tuner_detach(struct i2c_client *client) 1136static int tuner_remove(struct i2c_client *client)
1146{ 1137{
1147 struct tuner *t = i2c_get_clientdata(client); 1138 struct tuner *t = i2c_get_clientdata(client);
1148 struct analog_tuner_ops *ops = t->fe.ops.analog_demod_ops; 1139 struct analog_tuner_ops *ops = t->fe.ops.analog_demod_ops;
1149 int err;
1150
1151 err = i2c_detach_client(t->i2c);
1152 if (err) {
1153 tuner_warn
1154 ("Client deregistration failed, client not detached.\n");
1155 return err;
1156 }
1157 1140
1158 if (ops && ops->release) 1141 if (ops && ops->release)
1159 ops->release(&t->fe); 1142 ops->release(&t->fe);
1160 1143
1161 list_del(&t->list); 1144 list_del(&t->list);
1162 kfree(t); 1145 kfree(t);
1163 kfree(client);
1164 return 0; 1146 return 0;
1165} 1147}
1166 1148
1167/* ----------------------------------------------------------------------- */ 1149/* ----------------------------------------------------------------------- */
1168 1150
1169static struct i2c_driver driver = { 1151static struct v4l2_i2c_driver_data v4l2_i2c_data = {
1170 .id = I2C_DRIVERID_TUNER, 1152 .name = "tuner",
1171 .attach_adapter = tuner_probe, 1153 .driverid = I2C_DRIVERID_TUNER,
1172 .detach_client = tuner_detach,
1173 .command = tuner_command, 1154 .command = tuner_command,
1155 .probe = tuner_probe,
1156 .remove = tuner_remove,
1174 .suspend = tuner_suspend, 1157 .suspend = tuner_suspend,
1175 .resume = tuner_resume, 1158 .resume = tuner_resume,
1176 .driver = { 1159 .legacy_probe = tuner_legacy_probe,
1177 .name = "tuner",
1178 },
1179}; 1160};
1180static struct i2c_client client_template = {
1181 .name = "(tuner unset)",
1182 .driver = &driver,
1183};
1184
1185static int __init tuner_init_module(void)
1186{
1187 return i2c_add_driver(&driver);
1188}
1189
1190static void __exit tuner_cleanup_module(void)
1191{
1192 i2c_del_driver(&driver);
1193}
1194 1161
1195module_init(tuner_init_module);
1196module_exit(tuner_cleanup_module);
1197 1162
1198/* 1163/*
1199 * Overrides for Emacs so that we follow Linus's tabbing style. 1164 * Overrides for Emacs so that we follow Linus's tabbing style.