diff options
Diffstat (limited to 'drivers/media/video/indycam.c')
| -rw-r--r-- | drivers/media/video/indycam.c | 470 |
1 files changed, 0 insertions, 470 deletions
diff --git a/drivers/media/video/indycam.c b/drivers/media/video/indycam.c deleted file mode 100644 index 84b9e4f2b3b..00000000000 --- a/drivers/media/video/indycam.c +++ /dev/null @@ -1,470 +0,0 @@ -/* - * indycam.c - Silicon Graphics IndyCam digital camera driver - * - * Copyright (C) 2003 Ladislav Michl <ladis@linux-mips.org> - * Copyright (C) 2004,2005 Mikael Nousiainen <tmnousia@cc.hut.fi> - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include <linux/delay.h> -#include <linux/errno.h> -#include <linux/fs.h> -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/major.h> -#include <linux/module.h> -#include <linux/mm.h> -#include <linux/slab.h> - -#include <linux/videodev.h> -/* IndyCam decodes stream of photons into digital image representation ;-) */ -#include <linux/video_decoder.h> -#include <linux/i2c.h> - -#include "indycam.h" - -#define INDYCAM_MODULE_VERSION "0.0.5" - -MODULE_DESCRIPTION("SGI IndyCam driver"); -MODULE_VERSION(INDYCAM_MODULE_VERSION); -MODULE_AUTHOR("Mikael Nousiainen <tmnousia@cc.hut.fi>"); -MODULE_LICENSE("GPL"); - -// #define INDYCAM_DEBUG - -#ifdef INDYCAM_DEBUG -#define dprintk(x...) printk("IndyCam: " x); -#define indycam_regdump(client) indycam_regdump_debug(client) -#else -#define dprintk(x...) -#define indycam_regdump(client) -#endif - -struct indycam { - struct i2c_client *client; - u8 version; -}; - -static struct i2c_driver i2c_driver_indycam; - -static const u8 initseq[] = { - INDYCAM_CONTROL_AGCENA, /* INDYCAM_CONTROL */ - INDYCAM_SHUTTER_60, /* INDYCAM_SHUTTER */ - INDYCAM_GAIN_DEFAULT, /* INDYCAM_GAIN */ - 0x00, /* INDYCAM_BRIGHTNESS (read-only) */ - INDYCAM_RED_BALANCE_DEFAULT, /* INDYCAM_RED_BALANCE */ - INDYCAM_BLUE_BALANCE_DEFAULT, /* INDYCAM_BLUE_BALANCE */ - INDYCAM_RED_SATURATION_DEFAULT, /* INDYCAM_RED_SATURATION */ - INDYCAM_BLUE_SATURATION_DEFAULT,/* INDYCAM_BLUE_SATURATION */ -}; - -/* IndyCam register handling */ - -static int indycam_read_reg(struct i2c_client *client, u8 reg, u8 *value) -{ - int ret; - - if (reg == INDYCAM_REG_RESET) { - dprintk("indycam_read_reg(): " - "skipping write-only register %d\n", reg); - *value = 0; - return 0; - } - - ret = i2c_smbus_read_byte_data(client, reg); - - if (ret < 0) { - printk(KERN_ERR "IndyCam: indycam_read_reg(): read failed, " - "register = 0x%02x\n", reg); - return ret; - } - - *value = (u8)ret; - - return 0; -} - -static int indycam_write_reg(struct i2c_client *client, u8 reg, u8 value) -{ - int err; - - if ((reg == INDYCAM_REG_BRIGHTNESS) - || (reg == INDYCAM_REG_VERSION)) { - dprintk("indycam_write_reg(): " - "skipping read-only register %d\n", reg); - return 0; - } - - dprintk("Writing Reg %d = 0x%02x\n", reg, value); - err = i2c_smbus_write_byte_data(client, reg, value); - - if (err) { - printk(KERN_ERR "IndyCam: indycam_write_reg(): write failed, " - "register = 0x%02x, value = 0x%02x\n", reg, value); - } - return err; -} - -static int indycam_write_block(struct i2c_client *client, u8 reg, - u8 length, u8 *data) -{ - int i, err; - - for (i = 0; i < length; i++) { - err = indycam_write_reg(client, reg + i, data[i]); - if (err) - return err; - } - - return 0; -} - -/* Helper functions */ - -#ifdef INDYCAM_DEBUG -static void indycam_regdump_debug(struct i2c_client *client) -{ - int i; - u8 val; - - for (i = 0; i < 9; i++) { - indycam_read_reg(client, i, &val); - dprintk("Reg %d = 0x%02x\n", i, val); - } -} -#endif - -static int indycam_get_control(struct i2c_client *client, - struct indycam_control *ctrl) -{ - struct indycam *camera = i2c_get_clientdata(client); - u8 reg; - int ret = 0; - - switch (ctrl->type) { - case INDYCAM_CONTROL_AGC: - case INDYCAM_CONTROL_AWB: - ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); - if (ret) - return -EIO; - if (ctrl->type == INDYCAM_CONTROL_AGC) - ctrl->value = (reg & INDYCAM_CONTROL_AGCENA) - ? 1 : 0; - else - ctrl->value = (reg & INDYCAM_CONTROL_AWBCTL) - ? 1 : 0; - break; - case INDYCAM_CONTROL_SHUTTER: - ret = indycam_read_reg(client, INDYCAM_REG_SHUTTER, ®); - if (ret) - return -EIO; - ctrl->value = ((s32)reg == 0x00) ? 0xff : ((s32)reg - 1); - break; - case INDYCAM_CONTROL_GAIN: - ret = indycam_read_reg(client, INDYCAM_REG_GAIN, ®); - if (ret) - return -EIO; - ctrl->value = (s32)reg; - break; - case INDYCAM_CONTROL_RED_BALANCE: - ret = indycam_read_reg(client, INDYCAM_REG_RED_BALANCE, ®); - if (ret) - return -EIO; - ctrl->value = (s32)reg; - break; - case INDYCAM_CONTROL_BLUE_BALANCE: - ret = indycam_read_reg(client, INDYCAM_REG_BLUE_BALANCE, ®); - if (ret) - return -EIO; - ctrl->value = (s32)reg; - break; - case INDYCAM_CONTROL_RED_SATURATION: - ret = indycam_read_reg(client, - INDYCAM_REG_RED_SATURATION, ®); - if (ret) - return -EIO; - ctrl->value = (s32)reg; - break; - case INDYCAM_CONTROL_BLUE_SATURATION: - ret = indycam_read_reg(client, - INDYCAM_REG_BLUE_SATURATION, ®); - if (ret) - return -EIO; - ctrl->value = (s32)reg; - break; - case INDYCAM_CONTROL_GAMMA: - if (camera->version == CAMERA_VERSION_MOOSE) { - ret = indycam_read_reg(client, - INDYCAM_REG_GAMMA, ®); - if (ret) - return -EIO; - ctrl->value = (s32)reg; - } else { - ctrl->value = INDYCAM_GAMMA_DEFAULT; - } - break; - default: - ret = -EINVAL; - } - - return ret; -} - -static int indycam_set_control(struct i2c_client *client, - struct indycam_control *ctrl) -{ - struct indycam *camera = i2c_get_clientdata(client); - u8 reg; - int ret = 0; - - switch (ctrl->type) { - case INDYCAM_CONTROL_AGC: - case INDYCAM_CONTROL_AWB: - ret = indycam_read_reg(client, INDYCAM_REG_CONTROL, ®); - if (ret) - break; - - if (ctrl->type == INDYCAM_CONTROL_AGC) { - if (ctrl->value) - reg |= INDYCAM_CONTROL_AGCENA; - else - reg &= ~INDYCAM_CONTROL_AGCENA; - } else { - if (ctrl->value) - reg |= INDYCAM_CONTROL_AWBCTL; - else - reg &= ~INDYCAM_CONTROL_AWBCTL; - } - - ret = indycam_write_reg(client, INDYCAM_REG_CONTROL, reg); - break; - case INDYCAM_CONTROL_SHUTTER: - reg = (ctrl->value == 0xff) ? 0x00 : (ctrl->value + 1); - ret = indycam_write_reg(client, INDYCAM_REG_SHUTTER, reg); - break; - case INDYCAM_CONTROL_GAIN: - ret = indycam_write_reg(client, INDYCAM_REG_GAIN, ctrl->value); - break; - case INDYCAM_CONTROL_RED_BALANCE: - ret = indycam_write_reg(client, INDYCAM_REG_RED_BALANCE, - ctrl->value); - break; - case INDYCAM_CONTROL_BLUE_BALANCE: - ret = indycam_write_reg(client, INDYCAM_REG_BLUE_BALANCE, - ctrl->value); - break; - case INDYCAM_CONTROL_RED_SATURATION: - ret = indycam_write_reg(client, INDYCAM_REG_RED_SATURATION, - ctrl->value); - break; - case INDYCAM_CONTROL_BLUE_SATURATION: - ret = indycam_write_reg(client, INDYCAM_REG_BLUE_SATURATION, - ctrl->value); - break; - case INDYCAM_CONTROL_GAMMA: - if (camera->version == CAMERA_VERSION_MOOSE) { - ret = indycam_write_reg(client, INDYCAM_REG_GAMMA, - ctrl->value); - } - break; - default: - ret = -EINVAL; - } - - return ret; -} - -/* I2C-interface */ - -static int indycam_attach(struct i2c_adapter *adap, int addr, int kind) -{ - int err = 0; - struct indycam *camera; - struct i2c_client *client; - - printk(KERN_INFO "SGI IndyCam driver version %s\n", - INDYCAM_MODULE_VERSION); - - client = kzalloc(sizeof(struct i2c_client), GFP_KERNEL); - if (!client) - return -ENOMEM; - camera = kzalloc(sizeof(struct indycam), GFP_KERNEL); - if (!camera) { - err = -ENOMEM; - goto out_free_client; - } - - client->addr = addr; - client->adapter = adap; - client->driver = &i2c_driver_indycam; - client->flags = 0; - strcpy(client->name, "IndyCam client"); - i2c_set_clientdata(client, camera); - - camera->client = client; - - err = i2c_attach_client(client); - if (err) - goto out_free_camera; - - camera->version = i2c_smbus_read_byte_data(client, - INDYCAM_REG_VERSION); - if (camera->version != CAMERA_VERSION_INDY && - camera->version != CAMERA_VERSION_MOOSE) { - err = -ENODEV; - goto out_detach_client; - } - printk(KERN_INFO "IndyCam v%d.%d detected\n", - INDYCAM_VERSION_MAJOR(camera->version), - INDYCAM_VERSION_MINOR(camera->version)); - - indycam_regdump(client); - - // initialize - err = indycam_write_block(client, 0, sizeof(initseq), (u8 *)&initseq); - if (err) { - printk(KERN_ERR "IndyCam initialization failed\n"); - err = -EIO; - goto out_detach_client; - } - - indycam_regdump(client); - - // white balance - err = indycam_write_reg(client, INDYCAM_REG_CONTROL, - INDYCAM_CONTROL_AGCENA | INDYCAM_CONTROL_AWBCTL); - if (err) { - printk(KERN_ERR "IndyCam: White balancing camera failed\n"); - err = -EIO; - goto out_detach_client; - } - - indycam_regdump(client); - - printk(KERN_INFO "IndyCam initialized\n"); - - return 0; - -out_detach_client: - i2c_detach_client(client); -out_free_camera: - kfree(camera); -out_free_client: - kfree(client); - return err; -} - -static int indycam_probe(struct i2c_adapter *adap) -{ - /* Indy specific crap */ - if (adap->id == I2C_HW_SGI_VINO) - return indycam_attach(adap, INDYCAM_ADDR, 0); - /* Feel free to add probe here :-) */ - return -ENODEV; -} - -static int indycam_detach(struct i2c_client *client) -{ - struct indycam *camera = i2c_get_clientdata(client); - - i2c_detach_client(client); - kfree(camera); - kfree(client); - return 0; -} - -static int indycam_command(struct i2c_client *client, unsigned int cmd, - void *arg) -{ - // struct indycam *camera = i2c_get_clientdata(client); - - /* The old video_decoder interface just isn't enough, - * so we'll use some custom commands. */ - switch (cmd) { - case DECODER_GET_CAPABILITIES: { - struct video_decoder_capability *cap = arg; - - cap->flags = VIDEO_DECODER_NTSC; - cap->inputs = 1; - cap->outputs = 1; - break; - } - case DECODER_GET_STATUS: { - int *iarg = arg; - - *iarg = DECODER_STATUS_GOOD | DECODER_STATUS_NTSC | - DECODER_STATUS_COLOR; - break; - } - case DECODER_SET_NORM: { - int *iarg = arg; - - switch (*iarg) { - case VIDEO_MODE_NTSC: - break; - default: - return -EINVAL; - } - break; - } - case DECODER_SET_INPUT: { - int *iarg = arg; - - if (*iarg != 0) - return -EINVAL; - break; - } - case DECODER_SET_OUTPUT: { - int *iarg = arg; - - if (*iarg != 0) - return -EINVAL; - break; - } - case DECODER_ENABLE_OUTPUT: { - /* Always enabled */ - break; - } - case DECODER_SET_PICTURE: { - // struct video_picture *pic = arg; - /* TODO: convert values for indycam_set_controls() */ - break; - } - case DECODER_INDYCAM_GET_CONTROL: { - return indycam_get_control(client, arg); - } - case DECODER_INDYCAM_SET_CONTROL: { - return indycam_set_control(client, arg); - } - default: - return -EINVAL; - } - - return 0; -} - -static struct i2c_driver i2c_driver_indycam = { - .driver = { - .name = "indycam", - }, - .id = I2C_DRIVERID_INDYCAM, - .attach_adapter = indycam_probe, - .detach_client = indycam_detach, - .command = indycam_command, -}; - -static int __init indycam_init(void) -{ - return i2c_add_driver(&i2c_driver_indycam); -} - -static void __exit indycam_exit(void) -{ - i2c_del_driver(&i2c_driver_indycam); -} - -module_init(indycam_init); -module_exit(indycam_exit); |
