tea6415c.c 3.3 KB

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