Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  * linux/drivers/video/riva/fbdev-i2c.c - nVidia i2c
  3  *
  4  * Maintained by Ani Joshi <ajoshi@shell.unixbox.com>
  5  *
  6  * Copyright 2004 Antonino A. Daplas <adaplas @pol.net>
  7  *
  8  * Based on radeonfb-i2c.c
  9  *
 10  * This file is subject to the terms and conditions of the GNU General Public
 11  * License.  See the file COPYING in the main directory of this archive
 12  * for more details.
 13  */
 14 
 15 #include <linux/config.h>
 16 #include <linux/module.h>
 17 #include <linux/kernel.h>
 18 #include <linux/sched.h>
 19 #include <linux/delay.h>
 20 #include <linux/pci.h>
 21 #include <linux/fb.h>
 22 #include <linux/jiffies.h>
 23 
 24 #include <asm/io.h>
 25 
 26 #include "rivafb.h"
 27 #include "../edid.h"
 28 
 29 #define RIVA_DDC        0x50
 30 
 31 static void riva_gpio_setscl(void* data, int state)
 32 {
 33         struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
 34         struct riva_par         *par = chan->par;
 35         u32                     val;
 36 
 37         VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
 38         val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
 39 
 40         if (state)
 41                 val |= 0x20;
 42         else
 43                 val &= ~0x20;
 44 
 45         VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
 46         VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
 47 }
 48 
 49 static void riva_gpio_setsda(void* data, int state)
 50 {
 51         struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
 52         struct riva_par         *par = chan->par;
 53         u32                     val;
 54 
 55         VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
 56         val = VGA_RD08(par->riva.PCIO, 0x3d5) & 0xf0;
 57 
 58         if (state)
 59                 val |= 0x10;
 60         else
 61                 val &= ~0x10;
 62 
 63         VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base + 1);
 64         VGA_WR08(par->riva.PCIO, 0x3d5, val | 0x1);
 65 }
 66 
 67 static int riva_gpio_getscl(void* data)
 68 {
 69         struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
 70         struct riva_par         *par = chan->par;
 71         u32                     val = 0;
 72 
 73         VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
 74         if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x04)
 75                 val = 1;
 76 
 77         val = VGA_RD08(par->riva.PCIO, 0x3d5);
 78 
 79         return val;
 80 }
 81 
 82 static int riva_gpio_getsda(void* data)
 83 {
 84         struct riva_i2c_chan    *chan = (struct riva_i2c_chan *)data;
 85         struct riva_par         *par = chan->par;
 86         u32                     val = 0;
 87 
 88         VGA_WR08(par->riva.PCIO, 0x3d4, chan->ddc_base);
 89         if (VGA_RD08(par->riva.PCIO, 0x3d5) & 0x08)
 90                 val = 1;
 91 
 92         return val;
 93 }
 94 
 95 #define I2C_ALGO_RIVA   0x0e0000
 96 static int riva_setup_i2c_bus(struct riva_i2c_chan *chan, const char *name)
 97 {
 98         int rc;
 99 
100         strcpy(chan->adapter.name, name);
101         chan->adapter.owner             = THIS_MODULE;
102         chan->adapter.id                = I2C_ALGO_RIVA;
103         chan->adapter.algo_data         = &chan->algo;
104         chan->adapter.dev.parent        = &chan->par->pdev->dev;
105         chan->algo.setsda               = riva_gpio_setsda;
106         chan->algo.setscl               = riva_gpio_setscl;
107         chan->algo.getsda               = riva_gpio_getsda;
108         chan->algo.getscl               = riva_gpio_getscl;
109         chan->algo.udelay               = 40;
110         chan->algo.timeout              = msecs_to_jiffies(2);
111         chan->algo.data                 = chan;
112 
113         i2c_set_adapdata(&chan->adapter, chan);
114 
115         /* Raise SCL and SDA */
116         riva_gpio_setsda(chan, 1);
117         riva_gpio_setscl(chan, 1);
118         udelay(20);
119 
120         rc = i2c_bit_add_bus(&chan->adapter);
121         if (rc == 0)
122                 dev_dbg(&chan->par->pdev->dev, "I2C bus %s registered.\n", name);
123         else
124                 dev_warn(&chan->par->pdev->dev, "Failed to register I2C bus %s.\n", name);
125         return rc;
126 }
127 
128 void riva_create_i2c_busses(struct riva_par *par)
129 {
130         par->bus = 3;
131 
132         par->chan[0].par        = par;
133         par->chan[1].par        = par;
134         par->chan[2].par        = par;
135 
136         par->chan[0].ddc_base = 0x3e;
137         par->chan[1].ddc_base = 0x36;
138         par->chan[2].ddc_base = 0x50;
139         riva_setup_i2c_bus(&par->chan[0], "BUS1");
140         riva_setup_i2c_bus(&par->chan[1], "BUS2");
141         riva_setup_i2c_bus(&par->chan[2], "BUS3");
142 }
143 
144 void riva_delete_i2c_busses(struct riva_par *par)
145 {
146         if (par->chan[0].par)
147                 i2c_bit_del_bus(&par->chan[0].adapter);
148         par->chan[0].par = NULL;
149 
150         if (par->chan[1].par)
151                 i2c_bit_del_bus(&par->chan[1].adapter);
152         par->chan[1].par = NULL;
153 
154         if (par->chan[2].par)
155                 i2c_bit_del_bus(&par->chan[2].adapter);
156         par->chan[2].par = NULL;
157 }
158 
159 static u8 *riva_do_probe_i2c_edid(struct riva_i2c_chan *chan)
160 {
161         u8 start = 0x0;
162         struct i2c_msg msgs[] = {
163                 {
164                         .addr   = RIVA_DDC,
165                         .len    = 1,
166                         .buf    = &start,
167                 }, {
168                         .addr   = RIVA_DDC,
169                         .flags  = I2C_M_RD,
170                         .len    = EDID_LENGTH,
171                 },
172         };
173         u8 *buf;
174 
175         buf = kmalloc(EDID_LENGTH, GFP_KERNEL);
176         if (!buf) {
177                 dev_warn(&chan->par->pdev->dev, "Out of memory!\n");
178                 return NULL;
179         }
180         msgs[1].buf = buf;
181 
182         if (i2c_transfer(&chan->adapter, msgs, 2) == 2)
183                 return buf;
184         dev_dbg(&chan->par->pdev->dev, "Unable to read EDID block.\n");
185         kfree(buf);
186         return NULL;
187 }
188 
189 int riva_probe_i2c_connector(struct riva_par *par, int conn, u8 **out_edid)
190 {
191         u8 *edid = NULL;
192         int i;
193 
194         for (i = 0; i < 3; i++) {
195                 /* Do the real work */
196                 edid = riva_do_probe_i2c_edid(&par->chan[conn-1]);
197                 if (edid)
198                         break;
199         }
200         if (out_edid)
201                 *out_edid = edid;
202         if (!edid)
203                 return 1;
204 
205         return 0;
206 }
207 
208 
  This page was automatically generated by the LXR engine.