Skip to content

Commit a637a11

Browse files
3x380Vralfbaechle
authored andcommitted
VINO driver version 0.0.5.
Second cut of the VINO / Indycam driver for the Silicon Graphics Indy, much more feature complete and bug free.
1 parent a06d61c commit a637a11

File tree

5 files changed

+1545
-680
lines changed

5 files changed

+1545
-680
lines changed

drivers/media/video/indycam.c

Lines changed: 163 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,15 @@
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

3432
MODULE_DESCRIPTION("SGI IndyCam driver");
3533
MODULE_VERSION(INDYCAM_MODULE_VERSION);
3634
MODULE_AUTHOR("Mikael Nousiainen <[email protected]>");
3735
MODULE_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

4747
struct indycam {
4848
struct i2c_client *client;
49-
int version;
49+
u8 version;
5050
};
5151

5252
static 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,
130129
static 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

389453
static 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

399463
static int __init indycam_init(void)

0 commit comments

Comments
 (0)