Commit 88b283281f1c783a79af175c400b5d20f10af2aa
Committed by
Jean Delvare
1 parent
1a31a88f4f
Exists in
master
and in
7 other branches
i2c: Improve the functionality documentation
Attempt to make the documentation about the I2C/SMBus functionality checking API clearer. Signed-off-by: Jean Delvare <khali@linux-fr.org>
Showing 1 changed file with 52 additions and 43 deletions Side-by-side Diff
Documentation/i2c/functionality
... | ... | @@ -51,26 +51,38 @@ |
51 | 51 | the transparent emulation layer) |
52 | 52 | |
53 | 53 | |
54 | -ALGORITHM/ADAPTER IMPLEMENTATION | |
55 | --------------------------------- | |
54 | +ADAPTER IMPLEMENTATION | |
55 | +---------------------- | |
56 | 56 | |
57 | -When you write a new algorithm driver, you will have to implement a | |
58 | -function callback `functionality', that gets an i2c_adapter structure | |
59 | -pointer as its only parameter: | |
57 | +When you write a new adapter driver, you will have to implement a | |
58 | +function callback `functionality'. Typical implementations are given | |
59 | +below. | |
60 | 60 | |
61 | - struct i2c_algorithm { | |
62 | - /* Many other things of course; check <linux/i2c.h>! */ | |
63 | - u32 (*functionality) (struct i2c_adapter *); | |
61 | +A typical SMBus-only adapter would list all the SMBus transactions it | |
62 | +supports. This example comes from the i2c-piix4 driver: | |
63 | + | |
64 | + static u32 piix4_func(struct i2c_adapter *adapter) | |
65 | + { | |
66 | + return I2C_FUNC_SMBUS_QUICK | I2C_FUNC_SMBUS_BYTE | | |
67 | + I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA | | |
68 | + I2C_FUNC_SMBUS_BLOCK_DATA; | |
64 | 69 | } |
65 | 70 | |
66 | -A typically implementation is given below, from i2c-algo-bit.c: | |
71 | +A typical full-I2C adapter would use the following (from the i2c-pxa | |
72 | +driver): | |
67 | 73 | |
68 | - static u32 bit_func(struct i2c_adapter *adap) | |
74 | + static u32 i2c_pxa_functionality(struct i2c_adapter *adap) | |
69 | 75 | { |
70 | - return I2C_FUNC_SMBUS_EMUL | I2C_FUNC_10BIT_ADDR | | |
71 | - I2C_FUNC_PROTOCOL_MANGLING; | |
76 | + return I2C_FUNC_I2C | I2C_FUNC_SMBUS_EMUL; | |
72 | 77 | } |
73 | 78 | |
79 | +I2C_FUNC_SMBUS_EMUL includes all the SMBus transactions (with the | |
80 | +addition of I2C block transactions) which i2c-core can emulate using | |
81 | +I2C_FUNC_I2C without any help from the adapter driver. The idea is | |
82 | +to let the client drivers check for the support of SMBus functions | |
83 | +without having to care whether the said functions are implemented in | |
84 | +hardware by the adapter, or emulated in software by i2c-core on top | |
85 | +of an I2C adapter. | |
74 | 86 | |
75 | 87 | |
76 | 88 | CLIENT CHECKING |
77 | 89 | |
78 | 90 | |
79 | 91 | |
80 | 92 | |
81 | 93 | |
82 | 94 | |
83 | 95 | |
84 | 96 | |
85 | 97 | |
... | ... | @@ -78,57 +90,54 @@ |
78 | 90 | |
79 | 91 | Before a client tries to attach to an adapter, or even do tests to check |
80 | 92 | whether one of the devices it supports is present on an adapter, it should |
81 | -check whether the needed functionality is present. There are two functions | |
82 | -defined which should be used instead of calling the functionality hook | |
83 | -in the algorithm structure directly: | |
93 | +check whether the needed functionality is present. The typical way to do | |
94 | +this is (from the lm75 driver): | |
84 | 95 | |
85 | - /* Return the functionality mask */ | |
86 | - extern u32 i2c_get_functionality (struct i2c_adapter *adap); | |
87 | - | |
88 | - /* Return 1 if adapter supports everything we need, 0 if not. */ | |
89 | - extern int i2c_check_functionality (struct i2c_adapter *adap, u32 func); | |
90 | - | |
91 | -This is a typical way to use these functions (from the writing-clients | |
92 | -document): | |
93 | - int foo_detect_client(struct i2c_adapter *adapter, int address, | |
94 | - unsigned short flags, int kind) | |
96 | + static int lm75_detect(...) | |
95 | 97 | { |
96 | - /* Define needed variables */ | |
97 | - | |
98 | - /* As the very first action, we check whether the adapter has the | |
99 | - needed functionality: we need the SMBus read_word_data, | |
100 | - write_word_data and write_byte functions in this example. */ | |
101 | - if (!i2c_check_functionality(adapter,I2C_FUNC_SMBUS_WORD_DATA | | |
102 | - I2C_FUNC_SMBUS_WRITE_BYTE)) | |
103 | - goto ERROR0; | |
104 | - | |
105 | - /* Now we can do the real detection */ | |
106 | - | |
107 | - ERROR0: | |
108 | - /* Return an error */ | |
98 | + (...) | |
99 | + if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA | | |
100 | + I2C_FUNC_SMBUS_WORD_DATA)) | |
101 | + goto exit; | |
102 | + (...) | |
109 | 103 | } |
110 | 104 | |
105 | +Here, the lm75 driver checks if the adapter can do both SMBus byte data | |
106 | +and SMBus word data transactions. If not, then the driver won't work on | |
107 | +this adapter and there's no point in going on. If the check above is | |
108 | +successful, then the driver knows that it can call the following | |
109 | +functions: i2c_smbus_read_byte_data(), i2c_smbus_write_byte_data(), | |
110 | +i2c_smbus_read_word_data() and i2c_smbus_write_word_data(). As a rule of | |
111 | +thumb, the functionality constants you test for with | |
112 | +i2c_check_functionality() should match exactly the i2c_smbus_* functions | |
113 | +which you driver is calling. | |
111 | 114 | |
115 | +Note that the check above doesn't tell whether the functionalities are | |
116 | +implemented in hardware by the underlying adapter or emulated in | |
117 | +software by i2c-core. Client drivers don't have to care about this, as | |
118 | +i2c-core will transparently implement SMBus transactions on top of I2C | |
119 | +adapters. | |
112 | 120 | |
121 | + | |
113 | 122 | CHECKING THROUGH /DEV |
114 | 123 | --------------------- |
115 | 124 | |
116 | 125 | If you try to access an adapter from a userspace program, you will have |
117 | 126 | to use the /dev interface. You will still have to check whether the |
118 | 127 | functionality you need is supported, of course. This is done using |
119 | -the I2C_FUNCS ioctl. An example, adapted from the lm_sensors i2cdetect | |
120 | -program, is below: | |
128 | +the I2C_FUNCS ioctl. An example, adapted from the i2cdetect program, is | |
129 | +below: | |
121 | 130 | |
122 | 131 | int file; |
123 | - if (file = open("/dev/i2c-0",O_RDWR) < 0) { | |
132 | + if (file = open("/dev/i2c-0", O_RDWR) < 0) { | |
124 | 133 | /* Some kind of error handling */ |
125 | 134 | exit(1); |
126 | 135 | } |
127 | - if (ioctl(file,I2C_FUNCS,&funcs) < 0) { | |
136 | + if (ioctl(file, I2C_FUNCS, &funcs) < 0) { | |
128 | 137 | /* Some kind of error handling */ |
129 | 138 | exit(1); |
130 | 139 | } |
131 | - if (! (funcs & I2C_FUNC_SMBUS_QUICK)) { | |
140 | + if (!(funcs & I2C_FUNC_SMBUS_QUICK)) { | |
132 | 141 | /* Oops, the needed functionality (SMBus write_quick function) is |
133 | 142 | not available! */ |
134 | 143 | exit(1); |