📄 sn9c102_core.c
字号:
NOTE 2: buffers are PAGE_SIZE long*/static ssize_t sn9c102_show_reg(struct device* cd, struct device_attribute *attr, char* buf){ struct sn9c102_device* cam; ssize_t count; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } count = sprintf(buf, "%u\n", cam->sysfs.reg); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_tsn9c102_store_reg(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ struct sn9c102_device* cam; u16 index; ssize_t count; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } index = sn9c102_strtou16(buf, len, &count); if (index >= ARRAY_SIZE(cam->reg) || !count) { mutex_unlock(&sn9c102_sysfs_lock); return -EINVAL; } cam->sysfs.reg = index; DBG(2, "Moved SN9C1XX register index to 0x%02X", cam->sysfs.reg); DBG(3, "Written bytes: %zd", count); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_t sn9c102_show_val(struct device* cd, struct device_attribute *attr, char* buf){ struct sn9c102_device* cam; ssize_t count; int val; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } if ((val = sn9c102_read_reg(cam, cam->sysfs.reg)) < 0) { mutex_unlock(&sn9c102_sysfs_lock); return -EIO; } count = sprintf(buf, "%d\n", val); DBG(3, "Read bytes: %zd, value: %d", count, val); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_tsn9c102_store_val(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ struct sn9c102_device* cam; u16 value; ssize_t count; int err; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } value = sn9c102_strtou16(buf, len, &count); if (!count) { mutex_unlock(&sn9c102_sysfs_lock); return -EINVAL; } err = sn9c102_write_reg(cam, value, cam->sysfs.reg); if (err) { mutex_unlock(&sn9c102_sysfs_lock); return -EIO; } DBG(2, "Written SN9C1XX reg. 0x%02X, val. 0x%02X", cam->sysfs.reg, value); DBG(3, "Written bytes: %zd", count); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_t sn9c102_show_i2c_reg(struct device* cd, struct device_attribute *attr, char* buf){ struct sn9c102_device* cam; ssize_t count; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } count = sprintf(buf, "%u\n", cam->sysfs.i2c_reg); DBG(3, "Read bytes: %zd", count); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_tsn9c102_store_i2c_reg(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ struct sn9c102_device* cam; u16 index; ssize_t count; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } index = sn9c102_strtou16(buf, len, &count); if (!count) { mutex_unlock(&sn9c102_sysfs_lock); return -EINVAL; } cam->sysfs.i2c_reg = index; DBG(2, "Moved sensor register index to 0x%02X", cam->sysfs.i2c_reg); DBG(3, "Written bytes: %zd", count); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_t sn9c102_show_i2c_val(struct device* cd, struct device_attribute *attr, char* buf){ struct sn9c102_device* cam; ssize_t count; int val; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } if (!(cam->sensor.sysfs_ops & SN9C102_I2C_READ)) { mutex_unlock(&sn9c102_sysfs_lock); return -ENOSYS; } if ((val = sn9c102_i2c_read(cam, cam->sysfs.i2c_reg)) < 0) { mutex_unlock(&sn9c102_sysfs_lock); return -EIO; } count = sprintf(buf, "%d\n", val); DBG(3, "Read bytes: %zd, value: %d", count, val); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_tsn9c102_store_i2c_val(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ struct sn9c102_device* cam; u16 value; ssize_t count; int err; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } if (!(cam->sensor.sysfs_ops & SN9C102_I2C_WRITE)) { mutex_unlock(&sn9c102_sysfs_lock); return -ENOSYS; } value = sn9c102_strtou16(buf, len, &count); if (!count) { mutex_unlock(&sn9c102_sysfs_lock); return -EINVAL; } err = sn9c102_i2c_write(cam, cam->sysfs.i2c_reg, value); if (err) { mutex_unlock(&sn9c102_sysfs_lock); return -EIO; } DBG(2, "Written sensor reg. 0x%02X, val. 0x%02X", cam->sysfs.i2c_reg, value); DBG(3, "Written bytes: %zd", count); mutex_unlock(&sn9c102_sysfs_lock); return count;}static ssize_tsn9c102_store_green(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ struct sn9c102_device* cam; enum sn9c102_bridge bridge; ssize_t res = 0; u16 value; ssize_t count; if (mutex_lock_interruptible(&sn9c102_sysfs_lock)) return -ERESTARTSYS; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) { mutex_unlock(&sn9c102_sysfs_lock); return -ENODEV; } bridge = cam->bridge; mutex_unlock(&sn9c102_sysfs_lock); value = sn9c102_strtou16(buf, len, &count); if (!count) return -EINVAL; switch (bridge) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: if (value > 0x0f) return -EINVAL; if ((res = sn9c102_store_reg(cd, attr, "0x11", 4)) >= 0) res = sn9c102_store_val(cd, attr, buf, len); break; case BRIDGE_SN9C103: case BRIDGE_SN9C105: case BRIDGE_SN9C120: if (value > 0x7f) return -EINVAL; if ((res = sn9c102_store_reg(cd, attr, "0x07", 4)) >= 0) res = sn9c102_store_val(cd, attr, buf, len); break; } return res;}static ssize_tsn9c102_store_blue(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ ssize_t res = 0; u16 value; ssize_t count; value = sn9c102_strtou16(buf, len, &count); if (!count || value > 0x7f) return -EINVAL; if ((res = sn9c102_store_reg(cd, attr, "0x06", 4)) >= 0) res = sn9c102_store_val(cd, attr, buf, len); return res;}static ssize_tsn9c102_store_red(struct device* cd, struct device_attribute *attr, const char* buf, size_t len){ ssize_t res = 0; u16 value; ssize_t count; value = sn9c102_strtou16(buf, len, &count); if (!count || value > 0x7f) return -EINVAL; if ((res = sn9c102_store_reg(cd, attr, "0x05", 4)) >= 0) res = sn9c102_store_val(cd, attr, buf, len); return res;}static ssize_t sn9c102_show_frame_header(struct device* cd, struct device_attribute *attr, char* buf){ struct sn9c102_device* cam; ssize_t count; cam = video_get_drvdata(container_of(cd, struct video_device, class_dev)); if (!cam) return -ENODEV; count = sizeof(cam->sysfs.frame_header); memcpy(buf, cam->sysfs.frame_header, count); DBG(3, "Frame header, read bytes: %zd", count); return count;}static DEVICE_ATTR(reg, S_IRUGO | S_IWUSR, sn9c102_show_reg, sn9c102_store_reg);static DEVICE_ATTR(val, S_IRUGO | S_IWUSR, sn9c102_show_val, sn9c102_store_val);static DEVICE_ATTR(i2c_reg, S_IRUGO | S_IWUSR, sn9c102_show_i2c_reg, sn9c102_store_i2c_reg);static DEVICE_ATTR(i2c_val, S_IRUGO | S_IWUSR, sn9c102_show_i2c_val, sn9c102_store_i2c_val);static DEVICE_ATTR(green, S_IWUGO, NULL, sn9c102_store_green);static DEVICE_ATTR(blue, S_IWUGO, NULL, sn9c102_store_blue);static DEVICE_ATTR(red, S_IWUGO, NULL, sn9c102_store_red);static DEVICE_ATTR(frame_header, S_IRUGO, sn9c102_show_frame_header, NULL);static int sn9c102_create_sysfs(struct sn9c102_device* cam){ struct device *classdev = &(cam->v4ldev->class_dev); int err = 0; if ((err = device_create_file(classdev, &dev_attr_reg))) goto err_out; if ((err = device_create_file(classdev, &dev_attr_val))) goto err_reg; if ((err = device_create_file(classdev, &dev_attr_frame_header))) goto err_val; if (cam->sensor.sysfs_ops) { if ((err = device_create_file(classdev, &dev_attr_i2c_reg))) goto err_frame_header; if ((err = device_create_file(classdev, &dev_attr_i2c_val))) goto err_i2c_reg; } if (cam->bridge == BRIDGE_SN9C101 || cam->bridge == BRIDGE_SN9C102) { if ((err = device_create_file(classdev, &dev_attr_green))) goto err_i2c_val; } else { if ((err = device_create_file(classdev, &dev_attr_blue))) goto err_i2c_val; if ((err = device_create_file(classdev, &dev_attr_red))) goto err_blue; } return 0;err_blue: device_remove_file(classdev, &dev_attr_blue);err_i2c_val: if (cam->sensor.sysfs_ops) device_remove_file(classdev, &dev_attr_i2c_val);err_i2c_reg: if (cam->sensor.sysfs_ops) device_remove_file(classdev, &dev_attr_i2c_reg);err_frame_header: device_remove_file(classdev, &dev_attr_frame_header);err_val: device_remove_file(classdev, &dev_attr_val);err_reg: device_remove_file(classdev, &dev_attr_reg);err_out: return err;}#endif /* CONFIG_VIDEO_ADV_DEBUG *//*****************************************************************************/static intsn9c102_set_pix_format(struct sn9c102_device* cam, struct v4l2_pix_format* pix){ int err = 0; if (pix->pixelformat == V4L2_PIX_FMT_SN9C10X || pix->pixelformat == V4L2_PIX_FMT_JPEG) { switch (cam->bridge) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: case BRIDGE_SN9C103: err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80, 0x18); break; case BRIDGE_SN9C105: case BRIDGE_SN9C120: err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f, 0x18); break; } } else { switch (cam->bridge) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: case BRIDGE_SN9C103: err += sn9c102_write_reg(cam, cam->reg[0x18] & 0x7f, 0x18); break; case BRIDGE_SN9C105: case BRIDGE_SN9C120: err += sn9c102_write_reg(cam, cam->reg[0x18] | 0x80, 0x18); break; } } return err ? -EIO : 0;}static intsn9c102_set_compression(struct sn9c102_device* cam, struct v4l2_jpegcompression* compression){ int i, err = 0; switch (cam->bridge) { case BRIDGE_SN9C101: case BRIDGE_SN9C102: case BRIDGE_SN9C103: if (compression->quality == 0) err += sn9c102_write_reg(cam, cam->reg[0x17] | 0x01, 0x17); else if (compression->quality == 1) err += sn9c102_write_reg(cam, cam->reg[0x17] & 0xfe, 0x17); break; case BRIDGE_SN9C105: case BRIDGE_SN9C120: if (compression->quality == 0) { for (i = 0; i <= 63; i++) { err += sn9c102_write_reg(cam,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -