aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/media/video/ivtv/ivtv-i2c.c
diff options
context:
space:
mode:
authorHans Verkuil <hverkuil@xs4all.nl>2008-11-29 17:38:23 -0500
committerMauro Carvalho Chehab <mchehab@redhat.com>2008-12-30 06:38:44 -0500
commit67ec09fdf5e05d4670b617256c696348b5df080b (patch)
treefdf5f16f9b20280f83ce10e435d557bcb371934f /drivers/media/video/ivtv/ivtv-i2c.c
parentca085fb900265b525e3f9fb95fb6d7fd27a302ea (diff)
V4L/DVB (9835): ivtv/ivtvfb: convert to v4l2_device/v4l2_subdev.
Signed-off-by: Hans Verkuil <hverkuil@xs4all.nl> Signed-off-by: Mauro Carvalho Chehab <mchehab@redhat.com>
Diffstat (limited to 'drivers/media/video/ivtv/ivtv-i2c.c')
-rw-r--r--drivers/media/video/ivtv/ivtv-i2c.c314
1 files changed, 67 insertions, 247 deletions
diff --git a/drivers/media/video/ivtv/ivtv-i2c.c b/drivers/media/video/ivtv/ivtv-i2c.c
index 41dbbe9621a1..ca1d9557945e 100644
--- a/drivers/media/video/ivtv/ivtv-i2c.c
+++ b/drivers/media/video/ivtv/ivtv-i2c.c
@@ -90,26 +90,6 @@
90#define IVTV_M52790_I2C_ADDR 0x48 90#define IVTV_M52790_I2C_ADDR 0x48
91 91
92/* This array should match the IVTV_HW_ defines */ 92/* This array should match the IVTV_HW_ defines */
93static const u8 hw_driverids[] = {
94 I2C_DRIVERID_CX25840,
95 I2C_DRIVERID_SAA711X,
96 I2C_DRIVERID_SAA7127,
97 I2C_DRIVERID_MSP3400,
98 I2C_DRIVERID_TUNER,
99 I2C_DRIVERID_WM8775,
100 I2C_DRIVERID_CS53L32A,
101 I2C_DRIVERID_TVEEPROM,
102 I2C_DRIVERID_SAA711X,
103 I2C_DRIVERID_UPD64031A,
104 I2C_DRIVERID_UPD64083,
105 I2C_DRIVERID_SAA717X,
106 I2C_DRIVERID_WM8739,
107 I2C_DRIVERID_VP27SMPX,
108 I2C_DRIVERID_M52790,
109 0 /* IVTV_HW_GPIO dummy driver ID */
110};
111
112/* This array should match the IVTV_HW_ defines */
113static const u8 hw_addrs[] = { 93static const u8 hw_addrs[] = {
114 IVTV_CX25840_I2C_ADDR, 94 IVTV_CX25840_I2C_ADDR,
115 IVTV_SAA7115_I2C_ADDR, 95 IVTV_SAA7115_I2C_ADDR,
@@ -130,6 +110,26 @@ static const u8 hw_addrs[] = {
130}; 110};
131 111
132/* This array should match the IVTV_HW_ defines */ 112/* This array should match the IVTV_HW_ defines */
113static const char *hw_modules[] = {
114 "cx25840",
115 "saa7115",
116 "saa7127",
117 "msp3400",
118 "tuner",
119 "wm8775",
120 "cs53l32a",
121 NULL,
122 "saa7115",
123 "upd64031a",
124 "upd64083",
125 "saa717x",
126 "wm8739",
127 "vp27smpx",
128 "m52790",
129 NULL
130};
131
132/* This array should match the IVTV_HW_ defines */
133static const char * const hw_devicenames[] = { 133static const char * const hw_devicenames[] = {
134 "cx25840", 134 "cx25840",
135 "saa7115", 135 "saa7115",
@@ -151,80 +151,58 @@ static const char * const hw_devicenames[] = {
151 151
152int ivtv_i2c_register(struct ivtv *itv, unsigned idx) 152int ivtv_i2c_register(struct ivtv *itv, unsigned idx)
153{ 153{
154 struct i2c_board_info info; 154 struct v4l2_subdev *sd;
155 struct i2c_client *c; 155 struct i2c_adapter *adap = &itv->i2c_adap;
156 u8 id; 156 const char *mod = hw_modules[idx];
157 int i; 157 const char *type = hw_devicenames[idx];
158 u32 hw = 1 << idx;
158 159
159 IVTV_DEBUG_I2C("i2c client register\n"); 160 if (idx >= ARRAY_SIZE(hw_addrs))
160 if (idx >= ARRAY_SIZE(hw_driverids) || hw_driverids[idx] == 0)
161 return -1; 161 return -1;
162 id = hw_driverids[idx]; 162 if (hw == IVTV_HW_TUNER) {
163 memset(&info, 0, sizeof(info)); 163 /* special tuner handling */
164 strlcpy(info.type, hw_devicenames[idx], sizeof(info.type)); 164 sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
165 info.addr = hw_addrs[idx]; 165 itv->card_i2c->radio);
166 for (i = 0; itv->i2c_clients[i] && i < I2C_CLIENTS_MAX; i++) {} 166 if (sd)
167 167 sd->grp_id = 1 << idx;
168 if (i == I2C_CLIENTS_MAX) { 168 sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
169 IVTV_ERR("insufficient room for new I2C client!\n"); 169 itv->card_i2c->demod);
170 return -ENOMEM; 170 if (sd)
171 sd->grp_id = 1 << idx;
172 sd = v4l2_i2c_new_probed_subdev(adap, mod, type,
173 itv->card_i2c->tv);
174 if (sd)
175 sd->grp_id = 1 << idx;
176 return sd ? 0 : -1;
171 } 177 }
178 if (!hw_addrs[idx])
179 return -1;
180 if (hw == IVTV_HW_UPD64031A || hw == IVTV_HW_UPD6408X) {
181 unsigned short addrs[2] = { hw_addrs[idx], I2C_CLIENT_END };
172 182
173 if (id != I2C_DRIVERID_TUNER) { 183 sd = v4l2_i2c_new_probed_subdev(adap, mod, type, addrs);
174 if (id == I2C_DRIVERID_UPD64031A || 184 } else {
175 id == I2C_DRIVERID_UPD64083) { 185 sd = v4l2_i2c_new_subdev(adap, mod, type, hw_addrs[idx]);
176 unsigned short addrs[2] = { info.addr, I2C_CLIENT_END };
177
178 c = i2c_new_probed_device(&itv->i2c_adap, &info, addrs);
179 } else
180 c = i2c_new_device(&itv->i2c_adap, &info);
181 if (c && c->driver == NULL)
182 i2c_unregister_device(c);
183 else if (c)
184 itv->i2c_clients[i] = c;
185 return itv->i2c_clients[i] ? 0 : -ENODEV;
186 } 186 }
187 187 if (sd)
188 /* special tuner handling */ 188 sd->grp_id = 1 << idx;
189 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->radio); 189 return sd ? 0 : -1;
190 if (c && c->driver == NULL)
191 i2c_unregister_device(c);
192 else if (c)
193 itv->i2c_clients[i++] = c;
194 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->demod);
195 if (c && c->driver == NULL)
196 i2c_unregister_device(c);
197 else if (c)
198 itv->i2c_clients[i++] = c;
199 c = i2c_new_probed_device(&itv->i2c_adap, &info, itv->card_i2c->tv);
200 if (c && c->driver == NULL)
201 i2c_unregister_device(c);
202 else if (c)
203 itv->i2c_clients[i++] = c;
204 return 0;
205}
206
207static int attach_inform(struct i2c_client *client)
208{
209 return 0;
210} 190}
211 191
212static int detach_inform(struct i2c_client *client) 192struct v4l2_subdev *ivtv_find_hw(struct ivtv *itv, u32 hw)
213{ 193{
214 int i; 194 struct v4l2_subdev *result = NULL;
215 struct ivtv *itv = (struct ivtv *)i2c_get_adapdata(client->adapter); 195 struct v4l2_subdev *sd;
216 196
217 IVTV_DEBUG_I2C("i2c client detach\n"); 197 spin_lock(&itv->device.lock);
218 for (i = 0; i < I2C_CLIENTS_MAX; i++) { 198 v4l2_device_for_each_subdev(sd, &itv->device) {
219 if (itv->i2c_clients[i] == client) { 199 if (sd->grp_id == hw) {
220 itv->i2c_clients[i] = NULL; 200 result = sd;
221 break; 201 break;
222 } 202 }
223 } 203 }
224 IVTV_DEBUG_I2C("i2c detach [client=%s,%s]\n", 204 spin_unlock(&itv->device.lock);
225 client->name, (i < I2C_CLIENTS_MAX) ? "ok" : "failed"); 205 return result;
226
227 return 0;
228} 206}
229 207
230/* Set the serial clock line to the desired state */ 208/* Set the serial clock line to the desired state */
@@ -494,7 +472,8 @@ static int ivtv_read(struct ivtv *itv, unsigned char addr, unsigned char *data,
494 intervening stop condition */ 472 intervening stop condition */
495static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num) 473static int ivtv_xfer(struct i2c_adapter *i2c_adap, struct i2c_msg *msgs, int num)
496{ 474{
497 struct ivtv *itv = i2c_get_adapdata(i2c_adap); 475 struct v4l2_device *drv = i2c_get_adapdata(i2c_adap);
476 struct ivtv *itv = to_ivtv(drv);
498 int retval; 477 int retval;
499 int i; 478 int i;
500 479
@@ -530,8 +509,6 @@ static struct i2c_adapter ivtv_i2c_adap_hw_template = {
530 .id = I2C_HW_B_CX2341X, 509 .id = I2C_HW_B_CX2341X,
531 .algo = &ivtv_algo, 510 .algo = &ivtv_algo,
532 .algo_data = NULL, /* filled from template */ 511 .algo_data = NULL, /* filled from template */
533 .client_register = attach_inform,
534 .client_unregister = detach_inform,
535 .owner = THIS_MODULE, 512 .owner = THIS_MODULE,
536}; 513};
537 514
@@ -583,8 +560,6 @@ static struct i2c_adapter ivtv_i2c_adap_template = {
583 .id = I2C_HW_B_CX2341X, 560 .id = I2C_HW_B_CX2341X,
584 .algo = NULL, /* set by i2c-algo-bit */ 561 .algo = NULL, /* set by i2c-algo-bit */
585 .algo_data = NULL, /* filled from template */ 562 .algo_data = NULL, /* filled from template */
586 .client_register = attach_inform,
587 .client_unregister = detach_inform,
588 .owner = THIS_MODULE, 563 .owner = THIS_MODULE,
589}; 564};
590 565
@@ -601,160 +576,6 @@ static struct i2c_client ivtv_i2c_client_template = {
601 .name = "ivtv internal", 576 .name = "ivtv internal",
602}; 577};
603 578
604int ivtv_call_i2c_client(struct ivtv *itv, int addr, unsigned int cmd, void *arg)
605{
606 struct i2c_client *client;
607 int retval;
608 int i;
609
610 IVTV_DEBUG_I2C("call_i2c_client addr=%02x\n", addr);
611 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
612 client = itv->i2c_clients[i];
613 if (client == NULL || client->driver == NULL ||
614 client->driver->command == NULL)
615 continue;
616 if (addr == client->addr) {
617 retval = client->driver->command(client, cmd, arg);
618 return retval;
619 }
620 }
621 if (cmd != VIDIOC_G_CHIP_IDENT)
622 IVTV_ERR("i2c addr 0x%02x not found for command 0x%x\n", addr, cmd);
623 return -ENODEV;
624}
625
626/* Find the i2c device based on the driver ID and return
627 its i2c address or -ENODEV if no matching device was found. */
628static int ivtv_i2c_id_addr(struct ivtv *itv, u32 id)
629{
630 struct i2c_client *client;
631 int retval = -ENODEV;
632 int i;
633
634 for (i = 0; i < I2C_CLIENTS_MAX; i++) {
635 client = itv->i2c_clients[i];
636 if (client == NULL || client->driver == NULL)
637 continue;
638 if (id == client->driver->id) {
639 retval = client->addr;
640 break;
641 }
642 }
643 return retval;
644}
645
646/* Find the i2c device name matching the DRIVERID */
647static const char *ivtv_i2c_id_name(u32 id)
648{
649 int i;
650
651 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
652 if (hw_driverids[i] == id)
653 return hw_devicenames[i];
654 return "unknown device";
655}
656
657/* Find the i2c device name matching the IVTV_HW_ flag */
658static const char *ivtv_i2c_hw_name(u32 hw)
659{
660 int i;
661
662 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
663 if (1 << i == hw)
664 return hw_devicenames[i];
665 return "unknown device";
666}
667
668/* Find the i2c device matching the IVTV_HW_ flag and return
669 its i2c address or -ENODEV if no matching device was found. */
670int ivtv_i2c_hw_addr(struct ivtv *itv, u32 hw)
671{
672 int i;
673
674 for (i = 0; i < ARRAY_SIZE(hw_driverids); i++)
675 if (1 << i == hw)
676 return ivtv_i2c_id_addr(itv, hw_driverids[i]);
677 return -ENODEV;
678}
679
680/* Calls i2c device based on IVTV_HW_ flag. If hw == 0, then do nothing.
681 If hw == IVTV_HW_GPIO then call the gpio handler. */
682int ivtv_i2c_hw(struct ivtv *itv, u32 hw, unsigned int cmd, void *arg)
683{
684 int addr;
685
686 if (hw == IVTV_HW_GPIO)
687 return ivtv_gpio(itv, cmd, arg);
688 if (hw == 0)
689 return 0;
690
691 addr = ivtv_i2c_hw_addr(itv, hw);
692 if (addr < 0) {
693 IVTV_ERR("i2c hardware 0x%08x (%s) not found for command 0x%x\n",
694 hw, ivtv_i2c_hw_name(hw), cmd);
695 return addr;
696 }
697 return ivtv_call_i2c_client(itv, addr, cmd, arg);
698}
699
700/* Calls i2c device based on I2C driver ID. */
701int ivtv_i2c_id(struct ivtv *itv, u32 id, unsigned int cmd, void *arg)
702{
703 int addr;
704
705 addr = ivtv_i2c_id_addr(itv, id);
706 if (addr < 0) {
707 if (cmd != VIDIOC_G_CHIP_IDENT)
708 IVTV_ERR("i2c ID 0x%08x (%s) not found for command 0x%x\n",
709 id, ivtv_i2c_id_name(id), cmd);
710 return addr;
711 }
712 return ivtv_call_i2c_client(itv, addr, cmd, arg);
713}
714
715int ivtv_cx25840(struct ivtv *itv, unsigned int cmd, void *arg)
716{
717 return ivtv_call_i2c_client(itv, IVTV_CX25840_I2C_ADDR, cmd, arg);
718}
719
720int ivtv_saa7115(struct ivtv *itv, unsigned int cmd, void *arg)
721{
722 return ivtv_call_i2c_client(itv, IVTV_SAA7115_I2C_ADDR, cmd, arg);
723}
724
725int ivtv_saa7127(struct ivtv *itv, unsigned int cmd, void *arg)
726{
727 return ivtv_call_i2c_client(itv, IVTV_SAA7127_I2C_ADDR, cmd, arg);
728}
729EXPORT_SYMBOL(ivtv_saa7127);
730
731int ivtv_saa717x(struct ivtv *itv, unsigned int cmd, void *arg)
732{
733 return ivtv_call_i2c_client(itv, IVTV_SAA717x_I2C_ADDR, cmd, arg);
734}
735
736int ivtv_upd64031a(struct ivtv *itv, unsigned int cmd, void *arg)
737{
738 return ivtv_call_i2c_client(itv, IVTV_UPD64031A_I2C_ADDR, cmd, arg);
739}
740
741int ivtv_upd64083(struct ivtv *itv, unsigned int cmd, void *arg)
742{
743 return ivtv_call_i2c_client(itv, IVTV_UPD64083_I2C_ADDR, cmd, arg);
744}
745
746/* broadcast cmd for all I2C clients and for the gpio subsystem */
747void ivtv_call_i2c_clients(struct ivtv *itv, unsigned int cmd, void *arg)
748{
749 if (itv->i2c_adap.algo == NULL) {
750 IVTV_ERR("Adapter is not set");
751 return;
752 }
753 i2c_clients_command(&itv->i2c_adap, cmd, arg);
754 if (itv->hw_flags & IVTV_HW_GPIO)
755 ivtv_gpio(itv, cmd, arg);
756}
757
758/* init + register i2c algo-bit adapter */ 579/* init + register i2c algo-bit adapter */
759int init_ivtv_i2c(struct ivtv *itv) 580int init_ivtv_i2c(struct ivtv *itv)
760{ 581{
@@ -763,10 +584,9 @@ int init_ivtv_i2c(struct ivtv *itv)
763 /* Sanity checks for the I2C hardware arrays. They must be the 584 /* Sanity checks for the I2C hardware arrays. They must be the
764 * same size and GPIO must be the last entry. 585 * same size and GPIO must be the last entry.
765 */ 586 */
766 if (ARRAY_SIZE(hw_driverids) != ARRAY_SIZE(hw_addrs) || 587 if (ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) ||
767 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_addrs) || 588 ARRAY_SIZE(hw_devicenames) != ARRAY_SIZE(hw_modules) ||
768 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1)) || 589 IVTV_HW_GPIO != (1 << (ARRAY_SIZE(hw_addrs) - 1))) {
769 hw_driverids[ARRAY_SIZE(hw_addrs) - 1]) {
770 IVTV_ERR("Mismatched I2C hardware arrays\n"); 590 IVTV_ERR("Mismatched I2C hardware arrays\n");
771 return -ENODEV; 591 return -ENODEV;
772 } 592 }
@@ -783,8 +603,8 @@ int init_ivtv_i2c(struct ivtv *itv)
783 itv->i2c_adap.algo_data = &itv->i2c_algo; 603 itv->i2c_adap.algo_data = &itv->i2c_algo;
784 604
785 sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d", 605 sprintf(itv->i2c_adap.name + strlen(itv->i2c_adap.name), " #%d",
786 itv->num); 606 itv->instance);
787 i2c_set_adapdata(&itv->i2c_adap, itv); 607 i2c_set_adapdata(&itv->i2c_adap, &itv->device);
788 608
789 memcpy(&itv->i2c_client, &ivtv_i2c_client_template, 609 memcpy(&itv->i2c_client, &ivtv_i2c_client_template,
790 sizeof(struct i2c_client)); 610 sizeof(struct i2c_client));