diff options
Diffstat (limited to 'drivers/net/wireless/libertas/if_spi.c')
-rw-r--r-- | drivers/net/wireless/libertas/if_spi.c | 126 |
1 files changed, 60 insertions, 66 deletions
diff --git a/drivers/net/wireless/libertas/if_spi.c b/drivers/net/wireless/libertas/if_spi.c index 5fa55fe1f860..f8c2898d82b0 100644 --- a/drivers/net/wireless/libertas/if_spi.c +++ b/drivers/net/wireless/libertas/if_spi.c | |||
@@ -19,7 +19,6 @@ | |||
19 | 19 | ||
20 | #include <linux/moduleparam.h> | 20 | #include <linux/moduleparam.h> |
21 | #include <linux/firmware.h> | 21 | #include <linux/firmware.h> |
22 | #include <linux/gpio.h> | ||
23 | #include <linux/jiffies.h> | 22 | #include <linux/jiffies.h> |
24 | #include <linux/kthread.h> | 23 | #include <linux/kthread.h> |
25 | #include <linux/list.h> | 24 | #include <linux/list.h> |
@@ -51,13 +50,6 @@ struct if_spi_card { | |||
51 | u16 card_id; | 50 | u16 card_id; |
52 | u8 card_rev; | 51 | u8 card_rev; |
53 | 52 | ||
54 | /* Pin number for our GPIO chip-select. */ | ||
55 | /* TODO: Once the generic SPI layer has some additional features, we | ||
56 | * should take this out and use the normal chip select here. | ||
57 | * We need support for chip select delays, and not dropping chipselect | ||
58 | * after each word. */ | ||
59 | int gpio_cs; | ||
60 | |||
61 | /* The last time that we initiated an SPU operation */ | 53 | /* The last time that we initiated an SPU operation */ |
62 | unsigned long prev_xfer_time; | 54 | unsigned long prev_xfer_time; |
63 | 55 | ||
@@ -119,9 +111,6 @@ static struct chip_ident chip_id_to_device_name[] = { | |||
119 | * First we have to put a SPU register name on the bus. Then we can | 111 | * First we have to put a SPU register name on the bus. Then we can |
120 | * either read from or write to that register. | 112 | * either read from or write to that register. |
121 | * | 113 | * |
122 | * For 16-bit transactions, byte order on the bus is big-endian. | ||
123 | * We don't have to worry about that here, though. | ||
124 | * The translation takes place in the SPI routines. | ||
125 | */ | 114 | */ |
126 | 115 | ||
127 | static void spu_transaction_init(struct if_spi_card *card) | 116 | static void spu_transaction_init(struct if_spi_card *card) |
@@ -133,12 +122,10 @@ static void spu_transaction_init(struct if_spi_card *card) | |||
133 | * If not, we have to busy-wait to be on the safe side. */ | 122 | * If not, we have to busy-wait to be on the safe side. */ |
134 | ndelay(400); | 123 | ndelay(400); |
135 | } | 124 | } |
136 | gpio_set_value(card->gpio_cs, 0); /* assert CS */ | ||
137 | } | 125 | } |
138 | 126 | ||
139 | static void spu_transaction_finish(struct if_spi_card *card) | 127 | static void spu_transaction_finish(struct if_spi_card *card) |
140 | { | 128 | { |
141 | gpio_set_value(card->gpio_cs, 1); /* drop CS */ | ||
142 | card->prev_xfer_time = jiffies; | 129 | card->prev_xfer_time = jiffies; |
143 | } | 130 | } |
144 | 131 | ||
@@ -147,7 +134,14 @@ static void spu_transaction_finish(struct if_spi_card *card) | |||
147 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | 134 | static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) |
148 | { | 135 | { |
149 | int err = 0; | 136 | int err = 0; |
150 | u16 reg_out = reg | IF_SPI_WRITE_OPERATION_MASK; | 137 | u16 reg_out = cpu_to_le16(reg | IF_SPI_WRITE_OPERATION_MASK); |
138 | struct spi_message m; | ||
139 | struct spi_transfer reg_trans; | ||
140 | struct spi_transfer data_trans; | ||
141 | |||
142 | spi_message_init(&m); | ||
143 | memset(®_trans, 0, sizeof(reg_trans)); | ||
144 | memset(&data_trans, 0, sizeof(data_trans)); | ||
151 | 145 | ||
152 | /* You must give an even number of bytes to the SPU, even if it | 146 | /* You must give an even number of bytes to the SPU, even if it |
153 | * doesn't care about the last one. */ | 147 | * doesn't care about the last one. */ |
@@ -156,29 +150,26 @@ static int spu_write(struct if_spi_card *card, u16 reg, const u8 *buf, int len) | |||
156 | spu_transaction_init(card); | 150 | spu_transaction_init(card); |
157 | 151 | ||
158 | /* write SPU register index */ | 152 | /* write SPU register index */ |
159 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 153 | reg_trans.tx_buf = ®_out; |
160 | if (err) | 154 | reg_trans.len = sizeof(reg_out); |
161 | goto out; | ||
162 | 155 | ||
163 | err = spi_write(card->spi, buf, len); | 156 | data_trans.tx_buf = buf; |
157 | data_trans.len = len; | ||
164 | 158 | ||
165 | out: | 159 | spi_message_add_tail(®_trans, &m); |
160 | spi_message_add_tail(&data_trans, &m); | ||
161 | |||
162 | err = spi_sync(card->spi, &m); | ||
166 | spu_transaction_finish(card); | 163 | spu_transaction_finish(card); |
167 | return err; | 164 | return err; |
168 | } | 165 | } |
169 | 166 | ||
170 | static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) | 167 | static inline int spu_write_u16(struct if_spi_card *card, u16 reg, u16 val) |
171 | { | 168 | { |
172 | return spu_write(card, reg, (u8 *)&val, sizeof(u16)); | 169 | u16 buff; |
173 | } | ||
174 | 170 | ||
175 | static inline int spu_write_u32(struct if_spi_card *card, u16 reg, u32 val) | 171 | buff = cpu_to_le16(val); |
176 | { | 172 | return spu_write(card, reg, (u8 *)&buff, sizeof(u16)); |
177 | /* The lower 16 bits are written first. */ | ||
178 | u16 out[2]; | ||
179 | out[0] = val & 0xffff; | ||
180 | out[1] = (val & 0xffff0000) >> 16; | ||
181 | return spu_write(card, reg, (u8 *)&out, sizeof(u32)); | ||
182 | } | 173 | } |
183 | 174 | ||
184 | static inline int spu_reg_is_port_reg(u16 reg) | 175 | static inline int spu_reg_is_port_reg(u16 reg) |
@@ -195,10 +186,13 @@ static inline int spu_reg_is_port_reg(u16 reg) | |||
195 | 186 | ||
196 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | 187 | static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) |
197 | { | 188 | { |
198 | unsigned int i, delay; | 189 | unsigned int delay; |
199 | int err = 0; | 190 | int err = 0; |
200 | u16 zero = 0; | 191 | u16 reg_out = cpu_to_le16(reg | IF_SPI_READ_OPERATION_MASK); |
201 | u16 reg_out = reg | IF_SPI_READ_OPERATION_MASK; | 192 | struct spi_message m; |
193 | struct spi_transfer reg_trans; | ||
194 | struct spi_transfer dummy_trans; | ||
195 | struct spi_transfer data_trans; | ||
202 | 196 | ||
203 | /* You must take an even number of bytes from the SPU, even if you | 197 | /* You must take an even number of bytes from the SPU, even if you |
204 | * don't care about the last one. */ | 198 | * don't care about the last one. */ |
@@ -206,29 +200,34 @@ static int spu_read(struct if_spi_card *card, u16 reg, u8 *buf, int len) | |||
206 | 200 | ||
207 | spu_transaction_init(card); | 201 | spu_transaction_init(card); |
208 | 202 | ||
203 | spi_message_init(&m); | ||
204 | memset(®_trans, 0, sizeof(reg_trans)); | ||
205 | memset(&dummy_trans, 0, sizeof(dummy_trans)); | ||
206 | memset(&data_trans, 0, sizeof(data_trans)); | ||
207 | |||
209 | /* write SPU register index */ | 208 | /* write SPU register index */ |
210 | err = spi_write(card->spi, (u8 *)®_out, sizeof(u16)); | 209 | reg_trans.tx_buf = ®_out; |
211 | if (err) | 210 | reg_trans.len = sizeof(reg_out); |
212 | goto out; | 211 | spi_message_add_tail(®_trans, &m); |
213 | 212 | ||
214 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : | 213 | delay = spu_reg_is_port_reg(reg) ? card->spu_port_delay : |
215 | card->spu_reg_delay; | 214 | card->spu_reg_delay; |
216 | if (card->use_dummy_writes) { | 215 | if (card->use_dummy_writes) { |
217 | /* Clock in dummy cycles while the SPU fills the FIFO */ | 216 | /* Clock in dummy cycles while the SPU fills the FIFO */ |
218 | for (i = 0; i < delay / 16; ++i) { | 217 | dummy_trans.len = delay / 8; |
219 | err = spi_write(card->spi, (u8 *)&zero, sizeof(u16)); | 218 | spi_message_add_tail(&dummy_trans, &m); |
220 | if (err) | ||
221 | return err; | ||
222 | } | ||
223 | } else { | 219 | } else { |
224 | /* Busy-wait while the SPU fills the FIFO */ | 220 | /* Busy-wait while the SPU fills the FIFO */ |
225 | ndelay(100 + (delay * 10)); | 221 | reg_trans.delay_usecs = |
222 | DIV_ROUND_UP((100 + (delay * 10)), 1000); | ||
226 | } | 223 | } |
227 | 224 | ||
228 | /* read in data */ | 225 | /* read in data */ |
229 | err = spi_read(card->spi, buf, len); | 226 | data_trans.rx_buf = buf; |
227 | data_trans.len = len; | ||
228 | spi_message_add_tail(&data_trans, &m); | ||
230 | 229 | ||
231 | out: | 230 | err = spi_sync(card->spi, &m); |
232 | spu_transaction_finish(card); | 231 | spu_transaction_finish(card); |
233 | return err; | 232 | return err; |
234 | } | 233 | } |
@@ -236,18 +235,25 @@ out: | |||
236 | /* Read 16 bits from an SPI register */ | 235 | /* Read 16 bits from an SPI register */ |
237 | static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) | 236 | static inline int spu_read_u16(struct if_spi_card *card, u16 reg, u16 *val) |
238 | { | 237 | { |
239 | return spu_read(card, reg, (u8 *)val, sizeof(u16)); | 238 | u16 buf; |
239 | int ret; | ||
240 | |||
241 | ret = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); | ||
242 | if (ret == 0) | ||
243 | *val = le16_to_cpup(&buf); | ||
244 | return ret; | ||
240 | } | 245 | } |
241 | 246 | ||
242 | /* Read 32 bits from an SPI register. | 247 | /* Read 32 bits from an SPI register. |
243 | * The low 16 bits are read first. */ | 248 | * The low 16 bits are read first. */ |
244 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) | 249 | static int spu_read_u32(struct if_spi_card *card, u16 reg, u32 *val) |
245 | { | 250 | { |
246 | u16 buf[2]; | 251 | u32 buf; |
247 | int err; | 252 | int err; |
248 | err = spu_read(card, reg, (u8 *)buf, sizeof(u32)); | 253 | |
254 | err = spu_read(card, reg, (u8 *)&buf, sizeof(buf)); | ||
249 | if (!err) | 255 | if (!err) |
250 | *val = buf[0] | (buf[1] << 16); | 256 | *val = le32_to_cpup(&buf); |
251 | return err; | 257 | return err; |
252 | } | 258 | } |
253 | 259 | ||
@@ -1051,7 +1057,6 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1051 | spi_set_drvdata(spi, card); | 1057 | spi_set_drvdata(spi, card); |
1052 | card->pdata = pdata; | 1058 | card->pdata = pdata; |
1053 | card->spi = spi; | 1059 | card->spi = spi; |
1054 | card->gpio_cs = pdata->gpio_cs; | ||
1055 | card->prev_xfer_time = jiffies; | 1060 | card->prev_xfer_time = jiffies; |
1056 | 1061 | ||
1057 | sema_init(&card->spi_ready, 0); | 1062 | sema_init(&card->spi_ready, 0); |
@@ -1060,26 +1065,18 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1060 | INIT_LIST_HEAD(&card->data_packet_list); | 1065 | INIT_LIST_HEAD(&card->data_packet_list); |
1061 | spin_lock_init(&card->buffer_lock); | 1066 | spin_lock_init(&card->buffer_lock); |
1062 | 1067 | ||
1063 | /* set up GPIO CS line. TODO: use regular CS line */ | ||
1064 | err = gpio_request(card->gpio_cs, "if_spi_gpio_chip_select"); | ||
1065 | if (err) | ||
1066 | goto free_card; | ||
1067 | err = gpio_direction_output(card->gpio_cs, 1); | ||
1068 | if (err) | ||
1069 | goto free_gpio; | ||
1070 | |||
1071 | /* Initialize the SPI Interface Unit */ | 1068 | /* Initialize the SPI Interface Unit */ |
1072 | err = spu_init(card, pdata->use_dummy_writes); | 1069 | err = spu_init(card, pdata->use_dummy_writes); |
1073 | if (err) | 1070 | if (err) |
1074 | goto free_gpio; | 1071 | goto free_card; |
1075 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); | 1072 | err = spu_get_chip_revision(card, &card->card_id, &card->card_rev); |
1076 | if (err) | 1073 | if (err) |
1077 | goto free_gpio; | 1074 | goto free_card; |
1078 | 1075 | ||
1079 | /* Firmware load */ | 1076 | /* Firmware load */ |
1080 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); | 1077 | err = spu_read_u32(card, IF_SPI_SCRATCH_4_REG, &scratch); |
1081 | if (err) | 1078 | if (err) |
1082 | goto free_gpio; | 1079 | goto free_card; |
1083 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) | 1080 | if (scratch == SUCCESSFUL_FW_DOWNLOAD_MAGIC) |
1084 | lbs_deb_spi("Firmware is already loaded for " | 1081 | lbs_deb_spi("Firmware is already loaded for " |
1085 | "Marvell WLAN 802.11 adapter\n"); | 1082 | "Marvell WLAN 802.11 adapter\n"); |
@@ -1087,7 +1084,7 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1087 | err = if_spi_calculate_fw_names(card->card_id, | 1084 | err = if_spi_calculate_fw_names(card->card_id, |
1088 | card->helper_fw_name, card->main_fw_name); | 1085 | card->helper_fw_name, card->main_fw_name); |
1089 | if (err) | 1086 | if (err) |
1090 | goto free_gpio; | 1087 | goto free_card; |
1091 | 1088 | ||
1092 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " | 1089 | lbs_deb_spi("Initializing FW for Marvell WLAN 802.11 adapter " |
1093 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " | 1090 | "(chip_id = 0x%04x, chip_rev = 0x%02x) " |
@@ -1098,23 +1095,23 @@ static int __devinit if_spi_probe(struct spi_device *spi) | |||
1098 | spi->max_speed_hz); | 1095 | spi->max_speed_hz); |
1099 | err = if_spi_prog_helper_firmware(card); | 1096 | err = if_spi_prog_helper_firmware(card); |
1100 | if (err) | 1097 | if (err) |
1101 | goto free_gpio; | 1098 | goto free_card; |
1102 | err = if_spi_prog_main_firmware(card); | 1099 | err = if_spi_prog_main_firmware(card); |
1103 | if (err) | 1100 | if (err) |
1104 | goto free_gpio; | 1101 | goto free_card; |
1105 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); | 1102 | lbs_deb_spi("loaded FW for Marvell WLAN 802.11 adapter\n"); |
1106 | } | 1103 | } |
1107 | 1104 | ||
1108 | err = spu_set_interrupt_mode(card, 0, 1); | 1105 | err = spu_set_interrupt_mode(card, 0, 1); |
1109 | if (err) | 1106 | if (err) |
1110 | goto free_gpio; | 1107 | goto free_card; |
1111 | 1108 | ||
1112 | /* Register our card with libertas. | 1109 | /* Register our card with libertas. |
1113 | * This will call alloc_etherdev */ | 1110 | * This will call alloc_etherdev */ |
1114 | priv = lbs_add_card(card, &spi->dev); | 1111 | priv = lbs_add_card(card, &spi->dev); |
1115 | if (!priv) { | 1112 | if (!priv) { |
1116 | err = -ENOMEM; | 1113 | err = -ENOMEM; |
1117 | goto free_gpio; | 1114 | goto free_card; |
1118 | } | 1115 | } |
1119 | card->priv = priv; | 1116 | card->priv = priv; |
1120 | priv->card = card; | 1117 | priv->card = card; |
@@ -1159,8 +1156,6 @@ terminate_thread: | |||
1159 | if_spi_terminate_spi_thread(card); | 1156 | if_spi_terminate_spi_thread(card); |
1160 | remove_card: | 1157 | remove_card: |
1161 | lbs_remove_card(priv); /* will call free_netdev */ | 1158 | lbs_remove_card(priv); /* will call free_netdev */ |
1162 | free_gpio: | ||
1163 | gpio_free(card->gpio_cs); | ||
1164 | free_card: | 1159 | free_card: |
1165 | free_if_spi_card(card); | 1160 | free_if_spi_card(card); |
1166 | out: | 1161 | out: |
@@ -1181,7 +1176,6 @@ static int __devexit libertas_spi_remove(struct spi_device *spi) | |||
1181 | free_irq(spi->irq, card); | 1176 | free_irq(spi->irq, card); |
1182 | if_spi_terminate_spi_thread(card); | 1177 | if_spi_terminate_spi_thread(card); |
1183 | lbs_remove_card(priv); /* will call free_netdev */ | 1178 | lbs_remove_card(priv); /* will call free_netdev */ |
1184 | gpio_free(card->gpio_cs); | ||
1185 | if (card->pdata->teardown) | 1179 | if (card->pdata->teardown) |
1186 | card->pdata->teardown(spi); | 1180 | card->pdata->teardown(spi); |
1187 | free_if_spi_card(card); | 1181 | free_if_spi_card(card); |