tuner-i2c.h 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181
  1. /*
  2. tuner-i2c.h - i2c interface for different tuners
  3. Copyright (C) 2007 Michael Krufky (mkrufky@linuxtv.org)
  4. This program is free software; you can redistribute it and/or modify
  5. it under the terms of the GNU General Public License as published by
  6. the Free Software Foundation; either version 2 of the License, or
  7. (at your option) any later version.
  8. This program is distributed in the hope that it will be useful,
  9. but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. GNU General Public License for more details.
  12. You should have received a copy of the GNU General Public License
  13. along with this program; if not, write to the Free Software
  14. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15. */
  16. #ifndef __TUNER_I2C_H__
  17. #define __TUNER_I2C_H__
  18. #include <linux/i2c.h>
  19. struct tuner_i2c_props {
  20. u8 addr;
  21. struct i2c_adapter *adap;
  22. /* used for tuner instance management */
  23. int count;
  24. char *name;
  25. };
  26. static inline int tuner_i2c_xfer_send(struct tuner_i2c_props *props, char *buf, int len)
  27. {
  28. struct i2c_msg msg = { .addr = props->addr, .flags = 0,
  29. .buf = buf, .len = len };
  30. int ret = i2c_transfer(props->adap, &msg, 1);
  31. return (ret == 1) ? len : ret;
  32. }
  33. static inline int tuner_i2c_xfer_recv(struct tuner_i2c_props *props, char *buf, int len)
  34. {
  35. struct i2c_msg msg = { .addr = props->addr, .flags = I2C_M_RD,
  36. .buf = buf, .len = len };
  37. int ret = i2c_transfer(props->adap, &msg, 1);
  38. return (ret == 1) ? len : ret;
  39. }
  40. static inline int tuner_i2c_xfer_send_recv(struct tuner_i2c_props *props,
  41. char *obuf, int olen,
  42. char *ibuf, int ilen)
  43. {
  44. struct i2c_msg msg[2] = { { .addr = props->addr, .flags = 0,
  45. .buf = obuf, .len = olen },
  46. { .addr = props->addr, .flags = I2C_M_RD,
  47. .buf = ibuf, .len = ilen } };
  48. int ret = i2c_transfer(props->adap, msg, 2);
  49. return (ret == 2) ? ilen : ret;
  50. }
  51. /* Callers must declare as a global for the module:
  52. *
  53. * static LIST_HEAD(hybrid_tuner_instance_list);
  54. *
  55. * hybrid_tuner_instance_list should be the third argument
  56. * passed into hybrid_tuner_request_state().
  57. *
  58. * state structure must contain the following:
  59. *
  60. * struct list_head hybrid_tuner_instance_list;
  61. * struct tuner_i2c_props i2c_props;
  62. *
  63. * hybrid_tuner_instance_list (both within state structure and globally)
  64. * is only required if the driver is using hybrid_tuner_request_state
  65. * and hybrid_tuner_release_state to manage state sharing between
  66. * multiple instances of hybrid tuners.
  67. */
  68. #define tuner_printk(kernlvl, i2cprops, fmt, arg...) do { \
  69. printk(kernlvl "%s %d-%04x: " fmt, i2cprops.name, \
  70. i2cprops.adap ? \
  71. i2c_adapter_id(i2cprops.adap) : -1, \
  72. i2cprops.addr, ##arg); \
  73. } while (0)
  74. /* TO DO: convert all callers of these macros to pass in
  75. * struct tuner_i2c_props, then remove the macro wrappers */
  76. #define __tuner_warn(i2cprops, fmt, arg...) do { \
  77. tuner_printk(KERN_WARNING, i2cprops, fmt, ##arg); \
  78. } while (0)
  79. #define __tuner_info(i2cprops, fmt, arg...) do { \
  80. tuner_printk(KERN_INFO, i2cprops, fmt, ##arg); \
  81. } while (0)
  82. #define __tuner_err(i2cprops, fmt, arg...) do { \
  83. tuner_printk(KERN_ERR, i2cprops, fmt, ##arg); \
  84. } while (0)
  85. #define __tuner_dbg(i2cprops, fmt, arg...) do { \
  86. if ((debug)) \
  87. tuner_printk(KERN_DEBUG, i2cprops, fmt, ##arg); \
  88. } while (0)
  89. #define tuner_warn(fmt, arg...) __tuner_warn(priv->i2c_props, fmt, ##arg)
  90. #define tuner_info(fmt, arg...) __tuner_info(priv->i2c_props, fmt, ##arg)
  91. #define tuner_err(fmt, arg...) __tuner_err(priv->i2c_props, fmt, ##arg)
  92. #define tuner_dbg(fmt, arg...) __tuner_dbg(priv->i2c_props, fmt, ##arg)
  93. /****************************************************************************/
  94. /* The return value of hybrid_tuner_request_state indicates the number of
  95. * instances using this tuner object.
  96. *
  97. * 0 - no instances, indicates an error - kzalloc must have failed
  98. *
  99. * 1 - one instance, indicates that the tuner object was created successfully
  100. *
  101. * 2 (or more) instances, indicates that an existing tuner object was found
  102. */
  103. #define hybrid_tuner_request_state(type, state, list, i2cadap, i2caddr, devname)\
  104. ({ \
  105. int __ret = 0; \
  106. list_for_each_entry(state, &list, hybrid_tuner_instance_list) { \
  107. if (((i2cadap) && (state->i2c_props.adap)) && \
  108. ((i2c_adapter_id(state->i2c_props.adap) == \
  109. i2c_adapter_id(i2cadap)) && \
  110. (i2caddr == state->i2c_props.addr))) { \
  111. __tuner_info(state->i2c_props, \
  112. "attaching existing instance\n"); \
  113. state->i2c_props.count++; \
  114. __ret = state->i2c_props.count; \
  115. break; \
  116. } \
  117. } \
  118. if (0 == __ret) { \
  119. state = kzalloc(sizeof(type), GFP_KERNEL); \
  120. if (NULL == state) \
  121. goto __fail; \
  122. state->i2c_props.addr = i2caddr; \
  123. state->i2c_props.adap = i2cadap; \
  124. state->i2c_props.name = devname; \
  125. __tuner_info(state->i2c_props, \
  126. "creating new instance\n"); \
  127. list_add_tail(&state->hybrid_tuner_instance_list, &list);\
  128. state->i2c_props.count++; \
  129. __ret = state->i2c_props.count; \
  130. } \
  131. __fail: \
  132. __ret; \
  133. })
  134. #define hybrid_tuner_release_state(state) \
  135. ({ \
  136. int __ret; \
  137. state->i2c_props.count--; \
  138. __ret = state->i2c_props.count; \
  139. if (!state->i2c_props.count) { \
  140. __tuner_info(state->i2c_props, "destroying instance\n");\
  141. list_del(&state->hybrid_tuner_instance_list); \
  142. kfree(state); \
  143. } \
  144. __ret; \
  145. })
  146. #define hybrid_tuner_report_instance_count(state) \
  147. ({ \
  148. int __ret = 0; \
  149. if (state) \
  150. __ret = state->i2c_props.count; \
  151. __ret; \
  152. })
  153. #endif /* __TUNER_I2C_H__ */