aboutsummaryrefslogtreecommitdiffstats
path: root/vtx/i2c.h
blob: 931c89e99da025e94c4dab44f8af6885e176f84f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
#ifndef I2C_H
#define I2C_H

/*
 * linux i2c interface.  Works a little bit like the scsi subsystem.
 * There are:
 *
 *     i2c          the basic control module        (like scsi_mod)
 *     bus driver   a driver with a i2c bus         (hostadapter driver)
 *     chip driver  a driver for a chip connected
 *                  to a i2c bus                    (cdrom/hd driver)
 *
 + a devices will be attached to one bus and one chip driver.  Every chip
 * driver gets a unique ID.
 *
 * A chip driver can provide a ioctl-like callback for the
 * communication with other parts of the kernel (not every i2c chip is
 * useful without other devices, a TV card tuner for example). 
 *
 * "i2c internal" parts of the structs: only the i2c module is allowed to
 * write to them, for others they are read-only.
 *
 */

#define I2C_BUS_MAX       4    /* max # of bus drivers  */
#define I2C_DRIVER_MAX    8    /* max # of chip drivers */
#define I2C_DEVICE_MAX    8    /* max # if devices per bus/driver */

struct i2c_bus;
struct i2c_driver;
struct i2c_device;

#define I2C_DRIVERID_MSP3400     1
#define I2C_DRIVERID_TUNER       2

/*
 * struct for a driver for a i2c chip (tuner, soundprocessor,
 * videotext, ... ).
 *
 * a driver will register within the i2c module.  The i2c module will
 * callback the driver (i2c_attach) for every device it finds on a i2c
 * bus at the specified address.  If the driver decides to "accept"
 * the, device, it must return a struct i2c_device, and NULL
 * otherwise.
 *
 * i2c_detach = i2c_attach ** -1
 * 
 * i2c_command will be used to pass commands to the driver in a
 * ioctl-line manner.
 *
 */

struct i2c_driver {
    char           name[32];         /* some useful label         */
    int            id;               /* device type ID            */
    unsigned char  addr_l, addr_h;   /* address range of the chip */

    int (*attach)(struct i2c_device *device);
    int (*detach)(struct i2c_device *device);
    int (*command)(struct i2c_device *device,
		   unsigned int cmd, void *arg);

    /* i2c internal */
    struct i2c_device   *devices[I2C_DEVICE_MAX];
    int                 devcount;
};


/*
 * this holds the informations about a i2c bus available in the system.
 * 
 * a chip with a i2c bus interface (like bt848) registers the bus within
 * the i2c module. This struct provides functions to access the i2c bus.
 * 
 * One must hold the spinlock to access the i2c bus (XXX: is the irqsave
 * required? Maybe better use a semaphore?).
 * 
 * attach/detach_inform is a callback to inform the bus driver about
 * attached chip drivers.
 *
 */

/* needed: unsigned long flags */
#if LINUX_VERSION_CODE >= 0x020100
#define LOCK_I2C_BUS(bus)    spin_lock_irqsave(&(bus->bus_lock),flags);
#define UNLOCK_I2C_BUS(bus)  spin_unlock_irqrestore(&(bus->bus_lock),flags);
#else
#define LOCK_I2C_BUS(bus)    { save_flags(flags); cli(); }
#define UNLOCK_I2C_BUS(bus)  { restore_flags(flags);     }
#endif

struct i2c_bus {
    char  name[32];         /* some useful label */
    void  *data;            /* free for use by the bus driver */

#if LINUX_VERSION_CODE >= 0x020100
    spinlock_t bus_lock;
#endif

    /* attach/detach inform callbacks */
    void    (*attach_inform)(struct i2c_bus *bus, int id);
    void    (*detach_inform)(struct i2c_bus *bus, int id);

    /* Software I2C */
    void    (*i2c_setlines)(struct i2c_bus *bus, int ctrl, int data);
    int     (*i2c_getdataline)(struct i2c_bus *bus);

    /* Hardware I2C */
    int     (*i2c_read)(struct i2c_bus *bus, unsigned char addr);
    int     (*i2c_write)(struct i2c_bus *bus, unsigned char addr,
			 unsigned char b1, unsigned char b2, int both);

    /* internal data for i2c module */
    struct i2c_device   *devices[I2C_DEVICE_MAX];
    int                 devcount;
};


/*
 * this holds per-device data for a i2c device
 *
 */

struct i2c_device {
    char           name[32];         /* some useful label */
    void           *data;            /* free for use by the chip driver */
    unsigned char  addr;             /* chip addr */

    /* i2c internal */
    struct i2c_bus     *bus;
    struct i2c_driver  *driver;
};


/* ------------------------------------------------------------------- */
/* i2c module functions                                                */

/* register/unregister a i2c bus */
int i2c_register_bus(struct i2c_bus *bus);
int i2c_unregister_bus(struct i2c_bus *bus);

/* register/unregister a chip driver */
int i2c_register_driver(struct i2c_driver *driver);
int i2c_unregister_driver(struct i2c_driver *driver);

/* send a command to a chip using the ioctl-like callback interface */
int i2c_control_device(struct i2c_bus *bus, int id,
		       unsigned int cmd, void *arg);

/* i2c bus access functions */
void    i2c_start(struct i2c_bus *bus);
void    i2c_stop(struct i2c_bus *bus);
void    i2c_one(struct i2c_bus *bus);
void    i2c_zero(struct i2c_bus *bus);
int     i2c_ack(struct i2c_bus *bus);

int     i2c_sendbyte(struct i2c_bus *bus,unsigned char data,int wait_for_ack);
unsigned char i2c_readbyte(struct i2c_bus *bus,int last);

/* i2c (maybe) hardware functions */
int     i2c_read(struct i2c_bus *bus, unsigned char addr);
int     i2c_write(struct i2c_bus *bus, unsigned char addr,
		  unsigned char b1, unsigned char b2, int both);

#endif /* I2C_H */

Privacy Policy