2727
2828#include "indycam.h"
2929
30- //#define INDYCAM_DEBUG
31-
32- #define INDYCAM_MODULE_VERSION "0.0.3"
30+ #define INDYCAM_MODULE_VERSION "0.0.5"
3331
3432MODULE_DESCRIPTION ("SGI IndyCam driver" );
3533MODULE_VERSION (INDYCAM_MODULE_VERSION );
3634MODULE_AUTHOR (
"Mikael Nousiainen <[email protected] >" );
3735MODULE_LICENSE ("GPL" );
3836
37+ // #define INDYCAM_DEBUG
38+
3939#ifdef INDYCAM_DEBUG
4040#define dprintk (x ...) printk("IndyCam: " x);
4141#define indycam_regdump (client ) indycam_regdump_debug(client)
@@ -46,14 +46,14 @@ MODULE_LICENSE("GPL");
4646
4747struct indycam {
4848 struct i2c_client * client ;
49- int version ;
49+ u8 version ;
5050};
5151
5252static struct i2c_driver i2c_driver_indycam ;
5353
54- static const unsigned char initseq [] = {
54+ static const u8 initseq [] = {
5555 INDYCAM_CONTROL_AGCENA , /* INDYCAM_CONTROL */
56- INDYCAM_SHUTTER_DEFAULT , /* INDYCAM_SHUTTER */
56+ INDYCAM_SHUTTER_60 , /* INDYCAM_SHUTTER */
5757 INDYCAM_GAIN_DEFAULT , /* INDYCAM_GAIN */
5858 0x00 , /* INDYCAM_BRIGHTNESS (read-only) */
5959 INDYCAM_RED_BALANCE_DEFAULT , /* INDYCAM_RED_BALANCE */
@@ -64,58 +64,57 @@ static const unsigned char initseq[] = {
6464
6565/* IndyCam register handling */
6666
67- static int indycam_read_reg (struct i2c_client * client , unsigned char reg ,
68- unsigned char * value )
67+ static int indycam_read_reg (struct i2c_client * client , u8 reg , u8 * value )
6968{
7069 int ret ;
7170
72- if (reg == INDYCAM_RESET ) {
71+ if (reg == INDYCAM_REG_RESET ) {
7372 dprintk ("indycam_read_reg(): "
7473 "skipping write-only register %d\n" , reg );
7574 * value = 0 ;
7675 return 0 ;
7776 }
7877
7978 ret = i2c_smbus_read_byte_data (client , reg );
79+
8080 if (ret < 0 ) {
8181 printk (KERN_ERR "IndyCam: indycam_read_reg(): read failed, "
8282 "register = 0x%02x\n" , reg );
8383 return ret ;
8484 }
8585
86- * value = (unsigned char )ret ;
86+ * value = (u8 )ret ;
8787
8888 return 0 ;
8989}
9090
91- static int indycam_write_reg (struct i2c_client * client , unsigned char reg ,
92- unsigned char value )
91+ static int indycam_write_reg (struct i2c_client * client , u8 reg , u8 value )
9392{
9493 int err ;
9594
96- if ((reg == INDYCAM_BRIGHTNESS )
97- || (reg == INDYCAM_VERSION )) {
95+ if ((reg == INDYCAM_REG_BRIGHTNESS )
96+ || (reg == INDYCAM_REG_VERSION )) {
9897 dprintk ("indycam_write_reg(): "
9998 "skipping read-only register %d\n" , reg );
10099 return 0 ;
101100 }
102101
103102 dprintk ("Writing Reg %d = 0x%02x\n" , reg , value );
104103 err = i2c_smbus_write_byte_data (client , reg , value );
104+
105105 if (err ) {
106106 printk (KERN_ERR "IndyCam: indycam_write_reg(): write failed, "
107107 "register = 0x%02x, value = 0x%02x\n" , reg , value );
108108 }
109109 return err ;
110110}
111111
112- static int indycam_write_block (struct i2c_client * client , unsigned char reg ,
113- unsigned char length , unsigned char * data )
112+ static int indycam_write_block (struct i2c_client * client , u8 reg ,
113+ u8 length , u8 * data )
114114{
115- unsigned char i ;
116- int err ;
115+ int i , err ;
117116
118- for (i = reg ; i < length ; i ++ ) {
117+ for (i = 0 ; i < length ; i ++ ) {
119118 err = indycam_write_reg (client , reg + i , data [i ]);
120119 if (err )
121120 return err ;
@@ -130,7 +129,7 @@ static int indycam_write_block(struct i2c_client *client, unsigned char reg,
130129static void indycam_regdump_debug (struct i2c_client * client )
131130{
132131 int i ;
133- unsigned char val ;
132+ u8 val ;
134133
135134 for (i = 0 ; i < 9 ; i ++ ) {
136135 indycam_read_reg (client , i , & val );
@@ -139,76 +138,144 @@ static void indycam_regdump_debug(struct i2c_client *client)
139138}
140139#endif
141140
142- static int indycam_get_controls (struct i2c_client * client ,
143- struct indycam_control * ctrl )
141+ static int indycam_get_control (struct i2c_client * client ,
142+ struct indycam_control * ctrl )
144143{
145- unsigned char ctrl_reg ;
146-
147- indycam_read_reg (client , INDYCAM_CONTROL , & ctrl_reg );
148- ctrl -> agc = (ctrl_reg & INDYCAM_CONTROL_AGCENA )
149- ? INDYCAM_VALUE_ENABLED
150- : INDYCAM_VALUE_DISABLED ;
151- ctrl -> awb = (ctrl_reg & INDYCAM_CONTROL_AWBCTL )
152- ? INDYCAM_VALUE_ENABLED
153- : INDYCAM_VALUE_DISABLED ;
154- indycam_read_reg (client , INDYCAM_SHUTTER ,
155- (unsigned char * )& ctrl -> shutter );
156- indycam_read_reg (client , INDYCAM_GAIN ,
157- (unsigned char * )& ctrl -> gain );
158- indycam_read_reg (client , INDYCAM_RED_BALANCE ,
159- (unsigned char * )& ctrl -> red_balance );
160- indycam_read_reg (client , INDYCAM_BLUE_BALANCE ,
161- (unsigned char * )& ctrl -> blue_balance );
162- indycam_read_reg (client , INDYCAM_RED_SATURATION ,
163- (unsigned char * )& ctrl -> red_saturation );
164- indycam_read_reg (client , INDYCAM_BLUE_SATURATION ,
165- (unsigned char * )& ctrl -> blue_saturation );
166- indycam_read_reg (client , INDYCAM_GAMMA ,
167- (unsigned char * )& ctrl -> gamma );
144+ struct indycam * camera = i2c_get_clientdata (client );
145+ u8 reg ;
146+ int ret = 0 ;
147+
148+ switch (ctrl -> type ) {
149+ case INDYCAM_CONTROL_AGC :
150+ case INDYCAM_CONTROL_AWB :
151+ ret = indycam_read_reg (client , INDYCAM_REG_CONTROL , & reg );
152+ if (ret )
153+ return - EIO ;
154+ if (ctrl -> type == INDYCAM_CONTROL_AGC )
155+ ctrl -> value = (reg & INDYCAM_CONTROL_AGCENA )
156+ ? 1 : 0 ;
157+ else
158+ ctrl -> value = (reg & INDYCAM_CONTROL_AWBCTL )
159+ ? 1 : 0 ;
160+ break ;
161+ case INDYCAM_CONTROL_SHUTTER :
162+ ret = indycam_read_reg (client , INDYCAM_REG_SHUTTER , & reg );
163+ if (ret )
164+ return - EIO ;
165+ ctrl -> value = ((s32 )reg == 0x00 ) ? 0xff : ((s32 )reg - 1 );
166+ break ;
167+ case INDYCAM_CONTROL_GAIN :
168+ ret = indycam_read_reg (client , INDYCAM_REG_GAIN , & reg );
169+ if (ret )
170+ return - EIO ;
171+ ctrl -> value = (s32 )reg ;
172+ break ;
173+ case INDYCAM_CONTROL_RED_BALANCE :
174+ ret = indycam_read_reg (client , INDYCAM_REG_RED_BALANCE , & reg );
175+ if (ret )
176+ return - EIO ;
177+ ctrl -> value = (s32 )reg ;
178+ break ;
179+ case INDYCAM_CONTROL_BLUE_BALANCE :
180+ ret = indycam_read_reg (client , INDYCAM_REG_BLUE_BALANCE , & reg );
181+ if (ret )
182+ return - EIO ;
183+ ctrl -> value = (s32 )reg ;
184+ break ;
185+ case INDYCAM_CONTROL_RED_SATURATION :
186+ ret = indycam_read_reg (client ,
187+ INDYCAM_REG_RED_SATURATION , & reg );
188+ if (ret )
189+ return - EIO ;
190+ ctrl -> value = (s32 )reg ;
191+ break ;
192+ case INDYCAM_CONTROL_BLUE_SATURATION :
193+ ret = indycam_read_reg (client ,
194+ INDYCAM_REG_BLUE_SATURATION , & reg );
195+ if (ret )
196+ return - EIO ;
197+ ctrl -> value = (s32 )reg ;
198+ break ;
199+ case INDYCAM_CONTROL_GAMMA :
200+ if (camera -> version == CAMERA_VERSION_MOOSE ) {
201+ ret = indycam_read_reg (client ,
202+ INDYCAM_REG_GAMMA , & reg );
203+ if (ret )
204+ return - EIO ;
205+ ctrl -> value = (s32 )reg ;
206+ } else {
207+ ctrl -> value = INDYCAM_GAMMA_DEFAULT ;
208+ }
209+ break ;
210+ default :
211+ ret = - EINVAL ;
212+ }
168213
169- return 0 ;
214+ return ret ;
170215}
171216
172- static int indycam_set_controls (struct i2c_client * client ,
173- struct indycam_control * ctrl )
217+ static int indycam_set_control (struct i2c_client * client ,
218+ struct indycam_control * ctrl )
174219{
175- unsigned char ctrl_reg ;
220+ struct indycam * camera = i2c_get_clientdata (client );
221+ u8 reg ;
222+ int ret = 0 ;
223+
224+ switch (ctrl -> type ) {
225+ case INDYCAM_CONTROL_AGC :
226+ case INDYCAM_CONTROL_AWB :
227+ ret = indycam_read_reg (client , INDYCAM_REG_CONTROL , & reg );
228+ if (ret )
229+ break ;
176230
177- indycam_read_reg (client , INDYCAM_CONTROL , & ctrl_reg );
178- if (ctrl -> agc != INDYCAM_VALUE_UNCHANGED ) {
179- if (ctrl -> agc )
180- ctrl_reg |= INDYCAM_CONTROL_AGCENA ;
181- else
182- ctrl_reg &= ~INDYCAM_CONTROL_AGCENA ;
183- }
184- if (ctrl -> awb != INDYCAM_VALUE_UNCHANGED ) {
185- if (ctrl -> awb )
186- ctrl_reg |= INDYCAM_CONTROL_AWBCTL ;
187- else
188- ctrl_reg &= ~INDYCAM_CONTROL_AWBCTL ;
231+ if (ctrl -> type == INDYCAM_CONTROL_AGC ) {
232+ if (ctrl -> value )
233+ reg |= INDYCAM_CONTROL_AGCENA ;
234+ else
235+ reg &= ~INDYCAM_CONTROL_AGCENA ;
236+ } else {
237+ if (ctrl -> value )
238+ reg |= INDYCAM_CONTROL_AWBCTL ;
239+ else
240+ reg &= ~INDYCAM_CONTROL_AWBCTL ;
241+ }
242+
243+ ret = indycam_write_reg (client , INDYCAM_REG_CONTROL , reg );
244+ break ;
245+ case INDYCAM_CONTROL_SHUTTER :
246+ reg = (ctrl -> value == 0xff ) ? 0x00 : (ctrl -> value + 1 );
247+ ret = indycam_write_reg (client , INDYCAM_REG_SHUTTER , reg );
248+ break ;
249+ case INDYCAM_CONTROL_GAIN :
250+ ret = indycam_write_reg (client , INDYCAM_REG_GAIN , ctrl -> value );
251+ break ;
252+ case INDYCAM_CONTROL_RED_BALANCE :
253+ ret = indycam_write_reg (client , INDYCAM_REG_RED_BALANCE ,
254+ ctrl -> value );
255+ break ;
256+ case INDYCAM_CONTROL_BLUE_BALANCE :
257+ ret = indycam_write_reg (client , INDYCAM_REG_BLUE_BALANCE ,
258+ ctrl -> value );
259+ break ;
260+ case INDYCAM_CONTROL_RED_SATURATION :
261+ ret = indycam_write_reg (client , INDYCAM_REG_RED_SATURATION ,
262+ ctrl -> value );
263+ break ;
264+ case INDYCAM_CONTROL_BLUE_SATURATION :
265+ ret = indycam_write_reg (client , INDYCAM_REG_BLUE_SATURATION ,
266+ ctrl -> value );
267+ break ;
268+ case INDYCAM_CONTROL_GAMMA :
269+ if (camera -> version == CAMERA_VERSION_MOOSE ) {
270+ ret = indycam_write_reg (client , INDYCAM_REG_GAMMA ,
271+ ctrl -> value );
272+ }
273+ break ;
274+ default :
275+ ret = - EINVAL ;
189276 }
190- indycam_write_reg (client , INDYCAM_CONTROL , ctrl_reg );
191-
192- if (ctrl -> shutter >= 0 )
193- indycam_write_reg (client , INDYCAM_SHUTTER , ctrl -> shutter );
194- if (ctrl -> gain >= 0 )
195- indycam_write_reg (client , INDYCAM_GAIN , ctrl -> gain );
196- if (ctrl -> red_balance >= 0 )
197- indycam_write_reg (client , INDYCAM_RED_BALANCE ,
198- ctrl -> red_balance );
199- if (ctrl -> blue_balance >= 0 )
200- indycam_write_reg (client , INDYCAM_BLUE_BALANCE ,
201- ctrl -> blue_balance );
202- if (ctrl -> red_saturation >= 0 )
203- indycam_write_reg (client , INDYCAM_RED_SATURATION ,
204- ctrl -> red_saturation );
205- if (ctrl -> blue_saturation >= 0 )
206- indycam_write_reg (client , INDYCAM_BLUE_SATURATION ,
207- ctrl -> blue_saturation );
208- if (ctrl -> gamma >= 0 )
209- indycam_write_reg (client , INDYCAM_GAMMA , ctrl -> gamma );
210277
211- return 0 ;
278+ return ret ;
212279}
213280
214281/* I2C-interface */
@@ -247,7 +314,8 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
247314 if (err )
248315 goto out_free_camera ;
249316
250- camera -> version = i2c_smbus_read_byte_data (client , INDYCAM_VERSION );
317+ camera -> version = i2c_smbus_read_byte_data (client ,
318+ INDYCAM_REG_VERSION );
251319 if (camera -> version != CAMERA_VERSION_INDY &&
252320 camera -> version != CAMERA_VERSION_MOOSE ) {
253321 err = - ENODEV ;
@@ -260,8 +328,7 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
260328 indycam_regdump (client );
261329
262330 // initialize
263- err = indycam_write_block (client , 0 , sizeof (initseq ),
264- (unsigned char * )& initseq );
331+ err = indycam_write_block (client , 0 , sizeof (initseq ), (u8 * )& initseq );
265332 if (err ) {
266333 printk (KERN_ERR "IndyCam initalization failed\n" );
267334 err = - EIO ;
@@ -271,11 +338,10 @@ static int indycam_attach(struct i2c_adapter *adap, int addr, int kind)
271338 indycam_regdump (client );
272339
273340 // white balance
274- err = indycam_write_reg (client , INDYCAM_CONTROL ,
341+ err = indycam_write_reg (client , INDYCAM_REG_CONTROL ,
275342 INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL );
276343 if (err ) {
277- printk (KERN_ERR "IndyCam white balance "
278- "initialization failed\n" );
344+ printk (KERN_ERR "IndyCam: White balancing camera failed\n" );
279345 err = - EIO ;
280346 goto out_detach_client ;
281347 }
@@ -371,13 +437,11 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
371437 /* TODO: convert values for indycam_set_controls() */
372438 break ;
373439 }
374- case DECODER_INDYCAM_GET_CONTROLS : {
375- struct indycam_control * ctrl = arg ;
376- indycam_get_controls (client , ctrl );
440+ case DECODER_INDYCAM_GET_CONTROL : {
441+ return indycam_get_control (client , arg );
377442 }
378- case DECODER_INDYCAM_SET_CONTROLS : {
379- struct indycam_control * ctrl = arg ;
380- indycam_set_controls (client , ctrl );
443+ case DECODER_INDYCAM_SET_CONTROL : {
444+ return indycam_set_control (client , arg );
381445 }
382446 default :
383447 return - EINVAL ;
@@ -388,12 +452,12 @@ static int indycam_command(struct i2c_client *client, unsigned int cmd,
388452
389453static struct i2c_driver i2c_driver_indycam = {
390454 .owner = THIS_MODULE ,
391- .name = "indycam" ,
392- .id = I2C_DRIVERID_INDYCAM ,
393- .flags = I2C_DF_NOTIFY ,
455+ .name = "indycam" ,
456+ .id = I2C_DRIVERID_INDYCAM ,
457+ .flags = I2C_DF_NOTIFY ,
394458 .attach_adapter = indycam_probe ,
395- .detach_client = indycam_detach ,
396- .command = indycam_command ,
459+ .detach_client = indycam_detach ,
460+ .command = indycam_command ,
397461};
398462
399463static int __init indycam_init (void )
0 commit comments