brintos

brintos / linux-shallow public Read only

0
0
Text · 3.3 KiB · 4aaf663 Raw
159 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2 /*3    tea6415c - i2c-driver for the tea6415c by SGS Thomson4 5    Copyright (C) 1998-2003 Michael Hunold <michael@mihu.de>6    Copyright (C) 2008 Hans Verkuil <hverkuil@xs4all.nl>7 8    The tea6415c is a bus controlled video-matrix-switch9    with 8 inputs and 6 outputs.10    It is cascadable, i.e. it can be found at the addresses11    0x86 and 0x06 on the i2c-bus.12 13    For detailed information download the specifications directly14    from SGS Thomson at http://www.st.com15 16  */17 18 19#include <linux/module.h>20#include <linux/ioctl.h>21#include <linux/slab.h>22#include <linux/i2c.h>23#include <media/v4l2-device.h>24#include "tea6415c.h"25 26MODULE_AUTHOR("Michael Hunold <michael@mihu.de>");27MODULE_DESCRIPTION("tea6415c driver");28MODULE_LICENSE("GPL");29 30static int debug;31module_param(debug, int, 0644);32 33MODULE_PARM_DESC(debug, "Debug level (0-1)");34 35 36/* makes a connection between the input-pin 'i' and the output-pin 'o' */37static int tea6415c_s_routing(struct v4l2_subdev *sd,38			      u32 i, u32 o, u32 config)39{40	struct i2c_client *client = v4l2_get_subdevdata(sd);41	u8 byte = 0;42	int ret;43 44	v4l2_dbg(1, debug, sd, "i=%d, o=%d\n", i, o);45 46	/* check if the pins are valid */47	if (0 == ((1 == i ||  3 == i ||  5 == i ||  6 == i ||  8 == i || 10 == i || 20 == i || 11 == i)48	      && (18 == o || 17 == o || 16 == o || 15 == o || 14 == o || 13 == o)))49		return -EINVAL;50 51	/* to understand this, have a look at the tea6415c-specs (p.5) */52	switch (o) {53	case 18:54		byte = 0x00;55		break;56	case 14:57		byte = 0x20;58		break;59	case 16:60		byte = 0x10;61		break;62	case 17:63		byte = 0x08;64		break;65	case 15:66		byte = 0x18;67		break;68	case 13:69		byte = 0x28;70		break;71	}72 73	switch (i) {74	case 5:75		byte |= 0x00;76		break;77	case 8:78		byte |= 0x04;79		break;80	case 3:81		byte |= 0x02;82		break;83	case 20:84		byte |= 0x06;85		break;86	case 6:87		byte |= 0x01;88		break;89	case 10:90		byte |= 0x05;91		break;92	case 1:93		byte |= 0x03;94		break;95	case 11:96		byte |= 0x07;97		break;98	}99 100	ret = i2c_smbus_write_byte(client, byte);101	if (ret) {102		v4l2_dbg(1, debug, sd,103			"i2c_smbus_write_byte() failed, ret:%d\n", ret);104		return -EIO;105	}106	return ret;107}108 109/* ----------------------------------------------------------------------- */110 111static const struct v4l2_subdev_video_ops tea6415c_video_ops = {112	.s_routing = tea6415c_s_routing,113};114 115static const struct v4l2_subdev_ops tea6415c_ops = {116	.video = &tea6415c_video_ops,117};118 119static int tea6415c_probe(struct i2c_client *client)120{121	struct v4l2_subdev *sd;122 123	/* let's see whether this adapter can support what we need */124	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_WRITE_BYTE))125		return -EIO;126 127	v4l_info(client, "chip found @ 0x%x (%s)\n",128			client->addr << 1, client->adapter->name);129	sd = devm_kzalloc(&client->dev, sizeof(*sd), GFP_KERNEL);130	if (sd == NULL)131		return -ENOMEM;132	v4l2_i2c_subdev_init(sd, client, &tea6415c_ops);133	return 0;134}135 136static void tea6415c_remove(struct i2c_client *client)137{138	struct v4l2_subdev *sd = i2c_get_clientdata(client);139 140	v4l2_device_unregister_subdev(sd);141}142 143static const struct i2c_device_id tea6415c_id[] = {144	{ "tea6415c" },145	{ }146};147MODULE_DEVICE_TABLE(i2c, tea6415c_id);148 149static struct i2c_driver tea6415c_driver = {150	.driver = {151		.name	= "tea6415c",152	},153	.probe		= tea6415c_probe,154	.remove		= tea6415c_remove,155	.id_table	= tea6415c_id,156};157 158module_i2c_driver(tea6415c_driver);159