diff options
author | Helmut Buchsbaum <helmut.buchsbaum@gmail.com> | 2016-02-09 14:47:16 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-02-11 11:34:24 -0500 |
commit | 6665e62387c64054493411d00c7b0a5a37af88a5 (patch) | |
tree | 19cbc7ff8bae8ce95bdc9e8e4b410c76b5dc8574 | |
parent | cd6f288cbaab656cebd524c5ef2388c11378c827 (diff) |
net: phy: spi_ks8995: generalize creation of SPI commands
Prepare creating SPI reads and writes for other switch families.
The KS8995 family uses the straight forward
<8bit CMD><8bit ADDR>
sequence.
To be able to support KSZ8795 family, which uses
<3bit CMD><12bit ADDR><1 bit TR>
make the SPI command creation chip variant dependent.
Signed-off-by: Helmut Buchsbaum <helmut.buchsbaum@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/phy/spi_ks8995.c | 46 |
1 files changed, 35 insertions, 11 deletions
diff --git a/drivers/net/phy/spi_ks8995.c b/drivers/net/phy/spi_ks8995.c index 8258c166a767..9dcc5b4fd9d1 100644 --- a/drivers/net/phy/spi_ks8995.c +++ b/drivers/net/phy/spi_ks8995.c | |||
@@ -105,6 +105,8 @@ struct ks8995_chip_params { | |||
105 | int family_id; | 105 | int family_id; |
106 | int chip_id; | 106 | int chip_id; |
107 | int regs_size; | 107 | int regs_size; |
108 | int addr_width; | ||
109 | int addr_shift; | ||
108 | }; | 110 | }; |
109 | 111 | ||
110 | static const struct ks8995_chip_params ks8995_chip[] = { | 112 | static const struct ks8995_chip_params ks8995_chip[] = { |
@@ -113,12 +115,16 @@ static const struct ks8995_chip_params ks8995_chip[] = { | |||
113 | .family_id = FAMILY_KS8995, | 115 | .family_id = FAMILY_KS8995, |
114 | .chip_id = KS8995_CHIP_ID, | 116 | .chip_id = KS8995_CHIP_ID, |
115 | .regs_size = KS8995_REGS_SIZE, | 117 | .regs_size = KS8995_REGS_SIZE, |
118 | .addr_width = 8, | ||
119 | .addr_shift = 0, | ||
116 | }, | 120 | }, |
117 | [ksz8864] = { | 121 | [ksz8864] = { |
118 | .name = "KSZ8864RMN", | 122 | .name = "KSZ8864RMN", |
119 | .family_id = FAMILY_KS8995, | 123 | .family_id = FAMILY_KS8995, |
120 | .chip_id = KSZ8864_CHIP_ID, | 124 | .chip_id = KSZ8864_CHIP_ID, |
121 | .regs_size = KSZ8864_REGS_SIZE, | 125 | .regs_size = KSZ8864_REGS_SIZE, |
126 | .addr_width = 8, | ||
127 | .addr_shift = 0, | ||
122 | }, | 128 | }, |
123 | }; | 129 | }; |
124 | 130 | ||
@@ -153,20 +159,44 @@ static inline u8 get_chip_rev(u8 val) | |||
153 | return (val >> ID1_REVISION_S) & ID1_REVISION_M; | 159 | return (val >> ID1_REVISION_S) & ID1_REVISION_M; |
154 | } | 160 | } |
155 | 161 | ||
162 | /* create_spi_cmd - create a chip specific SPI command header | ||
163 | * @ks: pointer to switch instance | ||
164 | * @cmd: SPI command for switch | ||
165 | * @address: register address for command | ||
166 | * | ||
167 | * Different chip families use different bit pattern to address the switches | ||
168 | * registers: | ||
169 | * | ||
170 | * KS8995: 8bit command + 8bit address | ||
171 | * KSZ8795: 3bit command + 12bit address + 1bit TR (?) | ||
172 | */ | ||
173 | static inline __be16 create_spi_cmd(struct ks8995_switch *ks, int cmd, | ||
174 | unsigned address) | ||
175 | { | ||
176 | u16 result = cmd; | ||
177 | |||
178 | /* make room for address (incl. address shift) */ | ||
179 | result <<= ks->chip->addr_width + ks->chip->addr_shift; | ||
180 | /* add address */ | ||
181 | result |= address << ks->chip->addr_shift; | ||
182 | /* SPI protocol needs big endian */ | ||
183 | return cpu_to_be16(result); | ||
184 | } | ||
156 | /* ------------------------------------------------------------------------ */ | 185 | /* ------------------------------------------------------------------------ */ |
157 | static int ks8995_read(struct ks8995_switch *ks, char *buf, | 186 | static int ks8995_read(struct ks8995_switch *ks, char *buf, |
158 | unsigned offset, size_t count) | 187 | unsigned offset, size_t count) |
159 | { | 188 | { |
160 | u8 cmd[2]; | 189 | __be16 cmd; |
161 | struct spi_transfer t[2]; | 190 | struct spi_transfer t[2]; |
162 | struct spi_message m; | 191 | struct spi_message m; |
163 | int err; | 192 | int err; |
164 | 193 | ||
194 | cmd = create_spi_cmd(ks, KS8995_CMD_READ, offset); | ||
165 | spi_message_init(&m); | 195 | spi_message_init(&m); |
166 | 196 | ||
167 | memset(&t, 0, sizeof(t)); | 197 | memset(&t, 0, sizeof(t)); |
168 | 198 | ||
169 | t[0].tx_buf = cmd; | 199 | t[0].tx_buf = &cmd; |
170 | t[0].len = sizeof(cmd); | 200 | t[0].len = sizeof(cmd); |
171 | spi_message_add_tail(&t[0], &m); | 201 | spi_message_add_tail(&t[0], &m); |
172 | 202 | ||
@@ -174,9 +204,6 @@ static int ks8995_read(struct ks8995_switch *ks, char *buf, | |||
174 | t[1].len = count; | 204 | t[1].len = count; |
175 | spi_message_add_tail(&t[1], &m); | 205 | spi_message_add_tail(&t[1], &m); |
176 | 206 | ||
177 | cmd[0] = KS8995_CMD_READ; | ||
178 | cmd[1] = offset; | ||
179 | |||
180 | mutex_lock(&ks->lock); | 207 | mutex_lock(&ks->lock); |
181 | err = spi_sync(ks->spi, &m); | 208 | err = spi_sync(ks->spi, &m); |
182 | mutex_unlock(&ks->lock); | 209 | mutex_unlock(&ks->lock); |
@@ -184,20 +211,20 @@ static int ks8995_read(struct ks8995_switch *ks, char *buf, | |||
184 | return err ? err : count; | 211 | return err ? err : count; |
185 | } | 212 | } |
186 | 213 | ||
187 | |||
188 | static int ks8995_write(struct ks8995_switch *ks, char *buf, | 214 | static int ks8995_write(struct ks8995_switch *ks, char *buf, |
189 | unsigned offset, size_t count) | 215 | unsigned offset, size_t count) |
190 | { | 216 | { |
191 | u8 cmd[2]; | 217 | __be16 cmd; |
192 | struct spi_transfer t[2]; | 218 | struct spi_transfer t[2]; |
193 | struct spi_message m; | 219 | struct spi_message m; |
194 | int err; | 220 | int err; |
195 | 221 | ||
222 | cmd = create_spi_cmd(ks, KS8995_CMD_WRITE, offset); | ||
196 | spi_message_init(&m); | 223 | spi_message_init(&m); |
197 | 224 | ||
198 | memset(&t, 0, sizeof(t)); | 225 | memset(&t, 0, sizeof(t)); |
199 | 226 | ||
200 | t[0].tx_buf = cmd; | 227 | t[0].tx_buf = &cmd; |
201 | t[0].len = sizeof(cmd); | 228 | t[0].len = sizeof(cmd); |
202 | spi_message_add_tail(&t[0], &m); | 229 | spi_message_add_tail(&t[0], &m); |
203 | 230 | ||
@@ -205,9 +232,6 @@ static int ks8995_write(struct ks8995_switch *ks, char *buf, | |||
205 | t[1].len = count; | 232 | t[1].len = count; |
206 | spi_message_add_tail(&t[1], &m); | 233 | spi_message_add_tail(&t[1], &m); |
207 | 234 | ||
208 | cmd[0] = KS8995_CMD_WRITE; | ||
209 | cmd[1] = offset; | ||
210 | |||
211 | mutex_lock(&ks->lock); | 235 | mutex_lock(&ks->lock); |
212 | err = spi_sync(ks->spi, &m); | 236 | err = spi_sync(ks->spi, &m); |
213 | mutex_unlock(&ks->lock); | 237 | mutex_unlock(&ks->lock); |