root/drivers/media/tuners/tuner-i2c.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. tuner_i2c_xfer_send
  2. tuner_i2c_xfer_recv
  3. tuner_i2c_xfer_send_recv

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

/* [<][>][^][v][top][bottom][index][help] */