diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /drivers/usb/media/sn9c102_tas5130d1b.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'drivers/usb/media/sn9c102_tas5130d1b.c')
-rw-r--r-- | drivers/usb/media/sn9c102_tas5130d1b.c | 188 |
1 files changed, 188 insertions, 0 deletions
diff --git a/drivers/usb/media/sn9c102_tas5130d1b.c b/drivers/usb/media/sn9c102_tas5130d1b.c new file mode 100644 index 000000000000..b378e941bbe8 --- /dev/null +++ b/drivers/usb/media/sn9c102_tas5130d1b.c | |||
@@ -0,0 +1,188 @@ | |||
1 | /*************************************************************************** | ||
2 | * Plug-in for TAS5130D1B image sensor connected to the SN9C10x PC Camera * | ||
3 | * Controllers * | ||
4 | * * | ||
5 | * Copyright (C) 2004-2005 by Luca Risolia <luca.risolia@studio.unibo.it> * | ||
6 | * * | ||
7 | * This program is free software; you can redistribute it and/or modify * | ||
8 | * it under the terms of the GNU General Public License as published by * | ||
9 | * the Free Software Foundation; either version 2 of the License, or * | ||
10 | * (at your option) any later version. * | ||
11 | * * | ||
12 | * This program is distributed in the hope that it will be useful, * | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of * | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | ||
15 | * GNU General Public License for more details. * | ||
16 | * * | ||
17 | * You should have received a copy of the GNU General Public License * | ||
18 | * along with this program; if not, write to the Free Software * | ||
19 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | ||
20 | ***************************************************************************/ | ||
21 | |||
22 | #include "sn9c102_sensor.h" | ||
23 | |||
24 | |||
25 | static struct sn9c102_sensor tas5130d1b; | ||
26 | |||
27 | static struct v4l2_control tas5130d1b_gain, tas5130d1b_exposure; | ||
28 | |||
29 | |||
30 | static int tas5130d1b_init(struct sn9c102_device* cam) | ||
31 | { | ||
32 | int err = 0; | ||
33 | |||
34 | err += sn9c102_write_reg(cam, 0x01, 0x01); | ||
35 | err += sn9c102_write_reg(cam, 0x20, 0x17); | ||
36 | err += sn9c102_write_reg(cam, 0x04, 0x01); | ||
37 | err += sn9c102_write_reg(cam, 0x01, 0x10); | ||
38 | err += sn9c102_write_reg(cam, 0x00, 0x11); | ||
39 | err += sn9c102_write_reg(cam, 0x00, 0x14); | ||
40 | err += sn9c102_write_reg(cam, 0x60, 0x17); | ||
41 | err += sn9c102_write_reg(cam, 0x07, 0x18); | ||
42 | |||
43 | return err; | ||
44 | } | ||
45 | |||
46 | |||
47 | static int tas5130d1b_get_ctrl(struct sn9c102_device* cam, | ||
48 | struct v4l2_control* ctrl) | ||
49 | { | ||
50 | switch (ctrl->id) { | ||
51 | case V4L2_CID_GAIN: | ||
52 | ctrl->value = tas5130d1b_gain.value; | ||
53 | break; | ||
54 | case V4L2_CID_EXPOSURE: | ||
55 | ctrl->value = tas5130d1b_exposure.value; | ||
56 | break; | ||
57 | default: | ||
58 | return -EINVAL; | ||
59 | } | ||
60 | |||
61 | return 0; | ||
62 | } | ||
63 | |||
64 | |||
65 | static int tas5130d1b_set_ctrl(struct sn9c102_device* cam, | ||
66 | const struct v4l2_control* ctrl) | ||
67 | { | ||
68 | int err = 0; | ||
69 | |||
70 | switch (ctrl->id) { | ||
71 | case V4L2_CID_GAIN: | ||
72 | if (!(err += sn9c102_i2c_write(cam, 0x20, 0xf6 - ctrl->value))) | ||
73 | tas5130d1b_gain.value = ctrl->value; | ||
74 | break; | ||
75 | case V4L2_CID_EXPOSURE: | ||
76 | if (!(err += sn9c102_i2c_write(cam, 0x40, 0x47 - ctrl->value))) | ||
77 | tas5130d1b_exposure.value = ctrl->value; | ||
78 | break; | ||
79 | default: | ||
80 | return -EINVAL; | ||
81 | } | ||
82 | |||
83 | return err ? -EIO : 0; | ||
84 | } | ||
85 | |||
86 | |||
87 | static int tas5130d1b_set_crop(struct sn9c102_device* cam, | ||
88 | const struct v4l2_rect* rect) | ||
89 | { | ||
90 | struct sn9c102_sensor* s = &tas5130d1b; | ||
91 | u8 h_start = (u8)(rect->left - s->cropcap.bounds.left) + 104, | ||
92 | v_start = (u8)(rect->top - s->cropcap.bounds.top) + 12; | ||
93 | int err = 0; | ||
94 | |||
95 | err += sn9c102_write_reg(cam, h_start, 0x12); | ||
96 | err += sn9c102_write_reg(cam, v_start, 0x13); | ||
97 | |||
98 | /* Do NOT change! */ | ||
99 | err += sn9c102_write_reg(cam, 0x1f, 0x1a); | ||
100 | err += sn9c102_write_reg(cam, 0x1a, 0x1b); | ||
101 | err += sn9c102_write_reg(cam, sn9c102_pread_reg(cam, 0x19), 0x19); | ||
102 | |||
103 | return err; | ||
104 | } | ||
105 | |||
106 | |||
107 | static int tas5130d1b_set_pix_format(struct sn9c102_device* cam, | ||
108 | const struct v4l2_pix_format* pix) | ||
109 | { | ||
110 | int err = 0; | ||
111 | |||
112 | if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X) | ||
113 | err += sn9c102_write_reg(cam, 0x63, 0x19); | ||
114 | else | ||
115 | err += sn9c102_write_reg(cam, 0xf3, 0x19); | ||
116 | |||
117 | return err; | ||
118 | } | ||
119 | |||
120 | |||
121 | static struct sn9c102_sensor tas5130d1b = { | ||
122 | .name = "TAS5130D1B", | ||
123 | .maintainer = "Luca Risolia <luca.risolia@studio.unibo.it>", | ||
124 | .sysfs_ops = SN9C102_I2C_WRITE, | ||
125 | .frequency = SN9C102_I2C_100KHZ, | ||
126 | .interface = SN9C102_I2C_3WIRES, | ||
127 | .init = &tas5130d1b_init, | ||
128 | .qctrl = { | ||
129 | { | ||
130 | .id = V4L2_CID_GAIN, | ||
131 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
132 | .name = "global gain", | ||
133 | .minimum = 0x00, | ||
134 | .maximum = 0xf6, | ||
135 | .step = 0x02, | ||
136 | .default_value = 0x00, | ||
137 | .flags = 0, | ||
138 | }, | ||
139 | { | ||
140 | .id = V4L2_CID_EXPOSURE, | ||
141 | .type = V4L2_CTRL_TYPE_INTEGER, | ||
142 | .name = "exposure", | ||
143 | .minimum = 0x00, | ||
144 | .maximum = 0x47, | ||
145 | .step = 0x01, | ||
146 | .default_value = 0x00, | ||
147 | .flags = 0, | ||
148 | }, | ||
149 | }, | ||
150 | .get_ctrl = &tas5130d1b_get_ctrl, | ||
151 | .set_ctrl = &tas5130d1b_set_ctrl, | ||
152 | .cropcap = { | ||
153 | .bounds = { | ||
154 | .left = 0, | ||
155 | .top = 0, | ||
156 | .width = 640, | ||
157 | .height = 480, | ||
158 | }, | ||
159 | .defrect = { | ||
160 | .left = 0, | ||
161 | .top = 0, | ||
162 | .width = 640, | ||
163 | .height = 480, | ||
164 | }, | ||
165 | }, | ||
166 | .set_crop = &tas5130d1b_set_crop, | ||
167 | .pix_format = { | ||
168 | .width = 640, | ||
169 | .height = 480, | ||
170 | .pixelformat = V4L2_PIX_FMT_SBGGR8, | ||
171 | .priv = 8, | ||
172 | }, | ||
173 | .set_pix_format = &tas5130d1b_set_pix_format | ||
174 | }; | ||
175 | |||
176 | |||
177 | int sn9c102_probe_tas5130d1b(struct sn9c102_device* cam) | ||
178 | { | ||
179 | /* This sensor has no identifiers, so let's attach it anyway */ | ||
180 | sn9c102_attach_sensor(cam, &tas5130d1b); | ||
181 | |||
182 | /* Sensor detection is based on USB pid/vid */ | ||
183 | if (le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x6025 && | ||
184 | le16_to_cpu(tas5130d1b.usbdev->descriptor.idProduct) != 0x60aa) | ||
185 | return -ENODEV; | ||
186 | |||
187 | return 0; | ||
188 | } | ||