aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHelmut Buchsbaum <helmut.buchsbaum@gmail.com>2016-02-09 14:47:16 -0500
committerDavid S. Miller <davem@davemloft.net>2016-02-11 11:34:24 -0500
commit6665e62387c64054493411d00c7b0a5a37af88a5 (patch)
tree19cbc7ff8bae8ce95bdc9e8e4b410c76b5dc8574
parentcd6f288cbaab656cebd524c5ef2388c11378c827 (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.c46
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
110static const struct ks8995_chip_params ks8995_chip[] = { 112static 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 */
173static 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/* ------------------------------------------------------------------------ */
157static int ks8995_read(struct ks8995_switch *ks, char *buf, 186static 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
188static int ks8995_write(struct ks8995_switch *ks, char *buf, 214static 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);