spi.c (7429B)
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * This file is part of wl1251 4 * 5 * Copyright (C) 2008 Nokia Corporation 6 */ 7 8#include <linux/interrupt.h> 9#include <linux/irq.h> 10#include <linux/module.h> 11#include <linux/slab.h> 12#include <linux/swab.h> 13#include <linux/crc7.h> 14#include <linux/spi/spi.h> 15#include <linux/wl12xx.h> 16#include <linux/gpio.h> 17#include <linux/of.h> 18#include <linux/of_gpio.h> 19#include <linux/regulator/consumer.h> 20 21#include "wl1251.h" 22#include "reg.h" 23#include "spi.h" 24 25static irqreturn_t wl1251_irq(int irq, void *cookie) 26{ 27 struct wl1251 *wl; 28 29 wl1251_debug(DEBUG_IRQ, "IRQ"); 30 31 wl = cookie; 32 33 ieee80211_queue_work(wl->hw, &wl->irq_work); 34 35 return IRQ_HANDLED; 36} 37 38static struct spi_device *wl_to_spi(struct wl1251 *wl) 39{ 40 return wl->if_priv; 41} 42 43static void wl1251_spi_reset(struct wl1251 *wl) 44{ 45 u8 *cmd; 46 struct spi_transfer t; 47 struct spi_message m; 48 49 cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); 50 if (!cmd) { 51 wl1251_error("could not allocate cmd for spi reset"); 52 return; 53 } 54 55 memset(&t, 0, sizeof(t)); 56 spi_message_init(&m); 57 58 memset(cmd, 0xff, WSPI_INIT_CMD_LEN); 59 60 t.tx_buf = cmd; 61 t.len = WSPI_INIT_CMD_LEN; 62 spi_message_add_tail(&t, &m); 63 64 spi_sync(wl_to_spi(wl), &m); 65 66 wl1251_dump(DEBUG_SPI, "spi reset -> ", cmd, WSPI_INIT_CMD_LEN); 67 68 kfree(cmd); 69} 70 71static void wl1251_spi_wake(struct wl1251 *wl) 72{ 73 struct spi_transfer t; 74 struct spi_message m; 75 u8 *cmd = kzalloc(WSPI_INIT_CMD_LEN, GFP_KERNEL); 76 77 if (!cmd) { 78 wl1251_error("could not allocate cmd for spi init"); 79 return; 80 } 81 82 memset(&t, 0, sizeof(t)); 83 spi_message_init(&m); 84 85 /* Set WSPI_INIT_COMMAND 86 * the data is being send from the MSB to LSB 87 */ 88 cmd[0] = 0xff; 89 cmd[1] = 0xff; 90 cmd[2] = WSPI_INIT_CMD_START | WSPI_INIT_CMD_TX; 91 cmd[3] = 0; 92 cmd[4] = 0; 93 cmd[5] = HW_ACCESS_WSPI_INIT_CMD_MASK << 3; 94 cmd[5] |= HW_ACCESS_WSPI_FIXED_BUSY_LEN & WSPI_INIT_CMD_FIXEDBUSY_LEN; 95 96 cmd[6] = WSPI_INIT_CMD_IOD | WSPI_INIT_CMD_IP | WSPI_INIT_CMD_CS 97 | WSPI_INIT_CMD_WSPI | WSPI_INIT_CMD_WS; 98 99 if (HW_ACCESS_WSPI_FIXED_BUSY_LEN == 0) 100 cmd[6] |= WSPI_INIT_CMD_DIS_FIXEDBUSY; 101 else 102 cmd[6] |= WSPI_INIT_CMD_EN_FIXEDBUSY; 103 104 cmd[7] = crc7_be(0, cmd+2, WSPI_INIT_CMD_CRC_LEN) | WSPI_INIT_CMD_END; 105 /* 106 * The above is the logical order; it must actually be stored 107 * in the buffer byte-swapped. 108 */ 109 __swab32s((u32 *)cmd); 110 __swab32s((u32 *)cmd+1); 111 112 t.tx_buf = cmd; 113 t.len = WSPI_INIT_CMD_LEN; 114 spi_message_add_tail(&t, &m); 115 116 spi_sync(wl_to_spi(wl), &m); 117 118 wl1251_dump(DEBUG_SPI, "spi init -> ", cmd, WSPI_INIT_CMD_LEN); 119 120 kfree(cmd); 121} 122 123static void wl1251_spi_reset_wake(struct wl1251 *wl) 124{ 125 wl1251_spi_reset(wl); 126 wl1251_spi_wake(wl); 127} 128 129static void wl1251_spi_read(struct wl1251 *wl, int addr, void *buf, 130 size_t len) 131{ 132 struct spi_transfer t[3]; 133 struct spi_message m; 134 u8 *busy_buf; 135 u32 *cmd; 136 137 cmd = &wl->buffer_cmd; 138 busy_buf = wl->buffer_busyword; 139 140 *cmd = 0; 141 *cmd |= WSPI_CMD_READ; 142 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; 143 *cmd |= addr & WSPI_CMD_BYTE_ADDR; 144 145 spi_message_init(&m); 146 memset(t, 0, sizeof(t)); 147 148 t[0].tx_buf = cmd; 149 t[0].len = 4; 150 spi_message_add_tail(&t[0], &m); 151 152 /* Busy and non busy words read */ 153 t[1].rx_buf = busy_buf; 154 t[1].len = WL1251_BUSY_WORD_LEN; 155 spi_message_add_tail(&t[1], &m); 156 157 t[2].rx_buf = buf; 158 t[2].len = len; 159 spi_message_add_tail(&t[2], &m); 160 161 spi_sync(wl_to_spi(wl), &m); 162 163 /* FIXME: check busy words */ 164 165 wl1251_dump(DEBUG_SPI, "spi_read cmd -> ", cmd, sizeof(*cmd)); 166 wl1251_dump(DEBUG_SPI, "spi_read buf <- ", buf, len); 167} 168 169static void wl1251_spi_write(struct wl1251 *wl, int addr, void *buf, 170 size_t len) 171{ 172 struct spi_transfer t[2]; 173 struct spi_message m; 174 u32 *cmd; 175 176 cmd = &wl->buffer_cmd; 177 178 *cmd = 0; 179 *cmd |= WSPI_CMD_WRITE; 180 *cmd |= (len << WSPI_CMD_BYTE_LENGTH_OFFSET) & WSPI_CMD_BYTE_LENGTH; 181 *cmd |= addr & WSPI_CMD_BYTE_ADDR; 182 183 spi_message_init(&m); 184 memset(t, 0, sizeof(t)); 185 186 t[0].tx_buf = cmd; 187 t[0].len = sizeof(*cmd); 188 spi_message_add_tail(&t[0], &m); 189 190 t[1].tx_buf = buf; 191 t[1].len = len; 192 spi_message_add_tail(&t[1], &m); 193 194 spi_sync(wl_to_spi(wl), &m); 195 196 wl1251_dump(DEBUG_SPI, "spi_write cmd -> ", cmd, sizeof(*cmd)); 197 wl1251_dump(DEBUG_SPI, "spi_write buf -> ", buf, len); 198} 199 200static void wl1251_spi_enable_irq(struct wl1251 *wl) 201{ 202 return enable_irq(wl->irq); 203} 204 205static void wl1251_spi_disable_irq(struct wl1251 *wl) 206{ 207 return disable_irq(wl->irq); 208} 209 210static int wl1251_spi_set_power(struct wl1251 *wl, bool enable) 211{ 212 if (gpio_is_valid(wl->power_gpio)) 213 gpio_set_value(wl->power_gpio, enable); 214 215 return 0; 216} 217 218static const struct wl1251_if_operations wl1251_spi_ops = { 219 .read = wl1251_spi_read, 220 .write = wl1251_spi_write, 221 .reset = wl1251_spi_reset_wake, 222 .enable_irq = wl1251_spi_enable_irq, 223 .disable_irq = wl1251_spi_disable_irq, 224 .power = wl1251_spi_set_power, 225}; 226 227static int wl1251_spi_probe(struct spi_device *spi) 228{ 229 struct wl1251_platform_data *pdata = dev_get_platdata(&spi->dev); 230 struct device_node *np = spi->dev.of_node; 231 struct ieee80211_hw *hw; 232 struct wl1251 *wl; 233 int ret; 234 235 if (!np && !pdata) { 236 wl1251_error("no platform data"); 237 return -ENODEV; 238 } 239 240 hw = wl1251_alloc_hw(); 241 if (IS_ERR(hw)) 242 return PTR_ERR(hw); 243 244 wl = hw->priv; 245 246 SET_IEEE80211_DEV(hw, &spi->dev); 247 spi_set_drvdata(spi, wl); 248 wl->if_priv = spi; 249 wl->if_ops = &wl1251_spi_ops; 250 251 /* This is the only SPI value that we need to set here, the rest 252 * comes from the board-peripherals file 253 */ 254 spi->bits_per_word = 32; 255 256 ret = spi_setup(spi); 257 if (ret < 0) { 258 wl1251_error("spi_setup failed"); 259 goto out_free; 260 } 261 262 if (np) { 263 wl->use_eeprom = of_property_read_bool(np, "ti,wl1251-has-eeprom"); 264 wl->power_gpio = of_get_named_gpio(np, "ti,power-gpio", 0); 265 } else if (pdata) { 266 wl->power_gpio = pdata->power_gpio; 267 wl->use_eeprom = pdata->use_eeprom; 268 } 269 270 if (wl->power_gpio == -EPROBE_DEFER) { 271 ret = -EPROBE_DEFER; 272 goto out_free; 273 } 274 275 if (gpio_is_valid(wl->power_gpio)) { 276 ret = devm_gpio_request_one(&spi->dev, wl->power_gpio, 277 GPIOF_OUT_INIT_LOW, "wl1251 power"); 278 if (ret) { 279 wl1251_error("Failed to request gpio: %d\n", ret); 280 goto out_free; 281 } 282 } else { 283 wl1251_error("set power gpio missing in platform data"); 284 ret = -ENODEV; 285 goto out_free; 286 } 287 288 wl->irq = spi->irq; 289 if (wl->irq < 0) { 290 wl1251_error("irq missing in platform data"); 291 ret = -ENODEV; 292 goto out_free; 293 } 294 295 irq_set_status_flags(wl->irq, IRQ_NOAUTOEN); 296 ret = devm_request_irq(&spi->dev, wl->irq, wl1251_irq, 0, 297 DRIVER_NAME, wl); 298 if (ret < 0) { 299 wl1251_error("request_irq() failed: %d", ret); 300 goto out_free; 301 } 302 303 irq_set_irq_type(wl->irq, IRQ_TYPE_EDGE_RISING); 304 305 wl->vio = devm_regulator_get(&spi->dev, "vio"); 306 if (IS_ERR(wl->vio)) { 307 ret = PTR_ERR(wl->vio); 308 wl1251_error("vio regulator missing: %d", ret); 309 goto out_free; 310 } 311 312 ret = regulator_enable(wl->vio); 313 if (ret) 314 goto out_free; 315 316 ret = wl1251_init_ieee80211(wl); 317 if (ret) 318 goto disable_regulator; 319 320 return 0; 321 322disable_regulator: 323 regulator_disable(wl->vio); 324out_free: 325 ieee80211_free_hw(hw); 326 327 return ret; 328} 329 330static void wl1251_spi_remove(struct spi_device *spi) 331{ 332 struct wl1251 *wl = spi_get_drvdata(spi); 333 334 wl1251_free_hw(wl); 335 regulator_disable(wl->vio); 336} 337 338static struct spi_driver wl1251_spi_driver = { 339 .driver = { 340 .name = DRIVER_NAME, 341 }, 342 343 .probe = wl1251_spi_probe, 344 .remove = wl1251_spi_remove, 345}; 346 347module_spi_driver(wl1251_spi_driver); 348 349MODULE_LICENSE("GPL"); 350MODULE_AUTHOR("Kalle Valo <kvalo@adurom.com>"); 351MODULE_ALIAS("spi:wl1251");