From 03dd4cb26d967f9588437b0fc9cc0e8353322bb7 Mon Sep 17 00:00:00 2001 From: AndrĂ© Fabian Silva Delgado Date: Fri, 25 Mar 2016 03:53:42 -0300 Subject: Linux-libre 4.5-gnu --- drivers/net/wireless/cw1200/cw1200_spi.c | 476 ------------------------------- 1 file changed, 476 deletions(-) delete mode 100644 drivers/net/wireless/cw1200/cw1200_spi.c (limited to 'drivers/net/wireless/cw1200/cw1200_spi.c') diff --git a/drivers/net/wireless/cw1200/cw1200_spi.c b/drivers/net/wireless/cw1200/cw1200_spi.c deleted file mode 100644 index a74008363..000000000 --- a/drivers/net/wireless/cw1200/cw1200_spi.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Mac80211 SPI driver for ST-Ericsson CW1200 device - * - * Copyright (c) 2011, Sagrad Inc. - * Author: Solomon Peachy - * - * Based on cw1200_sdio.c - * Copyright (c) 2010, ST-Ericsson - * Author: Dmitry Tarnyagin - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "cw1200.h" -#include "hwbus.h" -#include -#include "hwio.h" - -MODULE_AUTHOR("Solomon Peachy "); -MODULE_DESCRIPTION("mac80211 ST-Ericsson CW1200 SPI driver"); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("spi:cw1200_wlan_spi"); - -/* #define SPI_DEBUG */ - -struct hwbus_priv { - struct spi_device *func; - struct cw1200_common *core; - const struct cw1200_platform_data_spi *pdata; - spinlock_t lock; /* Serialize all bus operations */ - wait_queue_head_t wq; - int claimed; -}; - -#define SDIO_TO_SPI_ADDR(addr) ((addr & 0x1f)>>2) -#define SET_WRITE 0x7FFF /* usage: and operation */ -#define SET_READ 0x8000 /* usage: or operation */ - -/* Notes on byte ordering: - LE: B0 B1 B2 B3 - BE: B3 B2 B1 B0 - - Hardware expects 32-bit data to be written as 16-bit BE words: - - B1 B0 B3 B2 -*/ - -static int cw1200_spi_memcpy_fromio(struct hwbus_priv *self, - unsigned int addr, - void *dst, int count) -{ - int ret, i; - u16 regaddr; - struct spi_message m; - - struct spi_transfer t_addr = { - .tx_buf = ®addr, - .len = sizeof(regaddr), - }; - struct spi_transfer t_msg = { - .rx_buf = dst, - .len = count, - }; - - regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; - regaddr |= SET_READ; - regaddr |= (count>>1); - -#ifdef SPI_DEBUG - pr_info("READ : %04d from 0x%02x (%04x)\n", count, addr, regaddr); -#endif - - /* Header is LE16 */ - regaddr = cpu_to_le16(regaddr); - - /* We have to byteswap if the SPI bus is limited to 8b operation - or we are running on a Big Endian system - */ -#if defined(__LITTLE_ENDIAN) - if (self->func->bits_per_word == 8) -#endif - regaddr = swab16(regaddr); - - spi_message_init(&m); - spi_message_add_tail(&t_addr, &m); - spi_message_add_tail(&t_msg, &m); - ret = spi_sync(self->func, &m); - -#ifdef SPI_DEBUG - pr_info("READ : "); - for (i = 0; i < t_addr.len; i++) - printk("%02x ", ((u8 *)t_addr.tx_buf)[i]); - printk(" : "); - for (i = 0; i < t_msg.len; i++) - printk("%02x ", ((u8 *)t_msg.rx_buf)[i]); - printk("\n"); -#endif - - /* We have to byteswap if the SPI bus is limited to 8b operation - or we are running on a Big Endian system - */ -#if defined(__LITTLE_ENDIAN) - if (self->func->bits_per_word == 8) -#endif - { - uint16_t *buf = (uint16_t *)dst; - for (i = 0; i < ((count + 1) >> 1); i++) - buf[i] = swab16(buf[i]); - } - - return ret; -} - -static int cw1200_spi_memcpy_toio(struct hwbus_priv *self, - unsigned int addr, - const void *src, int count) -{ - int rval, i; - u16 regaddr; - struct spi_transfer t_addr = { - .tx_buf = ®addr, - .len = sizeof(regaddr), - }; - struct spi_transfer t_msg = { - .tx_buf = src, - .len = count, - }; - struct spi_message m; - - regaddr = (SDIO_TO_SPI_ADDR(addr))<<12; - regaddr &= SET_WRITE; - regaddr |= (count>>1); - -#ifdef SPI_DEBUG - pr_info("WRITE: %04d to 0x%02x (%04x)\n", count, addr, regaddr); -#endif - - /* Header is LE16 */ - regaddr = cpu_to_le16(regaddr); - - /* We have to byteswap if the SPI bus is limited to 8b operation - or we are running on a Big Endian system - */ -#if defined(__LITTLE_ENDIAN) - if (self->func->bits_per_word == 8) -#endif - { - uint16_t *buf = (uint16_t *)src; - regaddr = swab16(regaddr); - for (i = 0; i < ((count + 1) >> 1); i++) - buf[i] = swab16(buf[i]); - } - -#ifdef SPI_DEBUG - pr_info("WRITE: "); - for (i = 0; i < t_addr.len; i++) - printk("%02x ", ((u8 *)t_addr.tx_buf)[i]); - printk(" : "); - for (i = 0; i < t_msg.len; i++) - printk("%02x ", ((u8 *)t_msg.tx_buf)[i]); - printk("\n"); -#endif - - spi_message_init(&m); - spi_message_add_tail(&t_addr, &m); - spi_message_add_tail(&t_msg, &m); - rval = spi_sync(self->func, &m); - -#ifdef SPI_DEBUG - pr_info("WROTE: %d\n", m.actual_length); -#endif - -#if defined(__LITTLE_ENDIAN) - /* We have to byteswap if the SPI bus is limited to 8b operation */ - if (self->func->bits_per_word == 8) -#endif - { - uint16_t *buf = (uint16_t *)src; - for (i = 0; i < ((count + 1) >> 1); i++) - buf[i] = swab16(buf[i]); - } - return rval; -} - -static void cw1200_spi_lock(struct hwbus_priv *self) -{ - unsigned long flags; - - DECLARE_WAITQUEUE(wait, current); - - might_sleep(); - - add_wait_queue(&self->wq, &wait); - spin_lock_irqsave(&self->lock, flags); - while (1) { - set_current_state(TASK_UNINTERRUPTIBLE); - if (!self->claimed) - break; - spin_unlock_irqrestore(&self->lock, flags); - schedule(); - spin_lock_irqsave(&self->lock, flags); - } - set_current_state(TASK_RUNNING); - self->claimed = 1; - spin_unlock_irqrestore(&self->lock, flags); - remove_wait_queue(&self->wq, &wait); - - return; -} - -static void cw1200_spi_unlock(struct hwbus_priv *self) -{ - unsigned long flags; - - spin_lock_irqsave(&self->lock, flags); - self->claimed = 0; - spin_unlock_irqrestore(&self->lock, flags); - wake_up(&self->wq); - - return; -} - -static irqreturn_t cw1200_spi_irq_handler(int irq, void *dev_id) -{ - struct hwbus_priv *self = dev_id; - - if (self->core) { - cw1200_spi_lock(self); - cw1200_irq_handler(self->core); - cw1200_spi_unlock(self); - return IRQ_HANDLED; - } else { - return IRQ_NONE; - } -} - -static int cw1200_spi_irq_subscribe(struct hwbus_priv *self) -{ - int ret; - - pr_debug("SW IRQ subscribe\n"); - - ret = request_threaded_irq(self->func->irq, NULL, - cw1200_spi_irq_handler, - IRQF_TRIGGER_HIGH | IRQF_ONESHOT, - "cw1200_wlan_irq", self); - if (WARN_ON(ret < 0)) - goto exit; - - ret = enable_irq_wake(self->func->irq); - if (WARN_ON(ret)) - goto free_irq; - - return 0; - -free_irq: - free_irq(self->func->irq, self); -exit: - return ret; -} - -static int cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) -{ - int ret = 0; - - pr_debug("SW IRQ unsubscribe\n"); - disable_irq_wake(self->func->irq); - free_irq(self->func->irq, self); - - return ret; -} - -static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) -{ - if (pdata->reset) { - gpio_set_value(pdata->reset, 0); - msleep(30); /* Min is 2 * CLK32K cycles */ - gpio_free(pdata->reset); - } - - if (pdata->power_ctrl) - pdata->power_ctrl(pdata, false); - if (pdata->clk_ctrl) - pdata->clk_ctrl(pdata, false); - - return 0; -} - -static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata) -{ - /* Ensure I/Os are pulled low */ - if (pdata->reset) { - gpio_request(pdata->reset, "cw1200_wlan_reset"); - gpio_direction_output(pdata->reset, 0); - } - if (pdata->powerup) { - gpio_request(pdata->powerup, "cw1200_wlan_powerup"); - gpio_direction_output(pdata->powerup, 0); - } - if (pdata->reset || pdata->powerup) - msleep(10); /* Settle time? */ - - /* Enable 3v3 and 1v8 to hardware */ - if (pdata->power_ctrl) { - if (pdata->power_ctrl(pdata, true)) { - pr_err("power_ctrl() failed!\n"); - return -1; - } - } - - /* Enable CLK32K */ - if (pdata->clk_ctrl) { - if (pdata->clk_ctrl(pdata, true)) { - pr_err("clk_ctrl() failed!\n"); - return -1; - } - msleep(10); /* Delay until clock is stable for 2 cycles */ - } - - /* Enable POWERUP signal */ - if (pdata->powerup) { - gpio_set_value(pdata->powerup, 1); - msleep(250); /* or more..? */ - } - /* Enable RSTn signal */ - if (pdata->reset) { - gpio_set_value(pdata->reset, 1); - msleep(50); /* Or more..? */ - } - return 0; -} - -static size_t cw1200_spi_align_size(struct hwbus_priv *self, size_t size) -{ - return size & 1 ? size + 1 : size; -} - -static int cw1200_spi_pm(struct hwbus_priv *self, bool suspend) -{ - return irq_set_irq_wake(self->func->irq, suspend); -} - -static struct hwbus_ops cw1200_spi_hwbus_ops = { - .hwbus_memcpy_fromio = cw1200_spi_memcpy_fromio, - .hwbus_memcpy_toio = cw1200_spi_memcpy_toio, - .lock = cw1200_spi_lock, - .unlock = cw1200_spi_unlock, - .align_size = cw1200_spi_align_size, - .power_mgmt = cw1200_spi_pm, -}; - -/* Probe Function to be called by SPI stack when device is discovered */ -static int cw1200_spi_probe(struct spi_device *func) -{ - const struct cw1200_platform_data_spi *plat_data = - dev_get_platdata(&func->dev); - struct hwbus_priv *self; - int status; - - /* Sanity check speed */ - if (func->max_speed_hz > 52000000) - func->max_speed_hz = 52000000; - if (func->max_speed_hz < 1000000) - func->max_speed_hz = 1000000; - - /* Fix up transfer size */ - if (plat_data->spi_bits_per_word) - func->bits_per_word = plat_data->spi_bits_per_word; - if (!func->bits_per_word) - func->bits_per_word = 16; - - /* And finally.. */ - func->mode = SPI_MODE_0; - - pr_info("cw1200_wlan_spi: Probe called (CS %d M %d BPW %d CLK %d)\n", - func->chip_select, func->mode, func->bits_per_word, - func->max_speed_hz); - - if (cw1200_spi_on(plat_data)) { - pr_err("spi_on() failed!\n"); - return -1; - } - - if (spi_setup(func)) { - pr_err("spi_setup() failed!\n"); - return -1; - } - - self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL); - if (!self) { - pr_err("Can't allocate SPI hwbus_priv."); - return -ENOMEM; - } - - self->pdata = plat_data; - self->func = func; - spin_lock_init(&self->lock); - - spi_set_drvdata(func, self); - - init_waitqueue_head(&self->wq); - - status = cw1200_spi_irq_subscribe(self); - - status = cw1200_core_probe(&cw1200_spi_hwbus_ops, - self, &func->dev, &self->core, - self->pdata->ref_clk, - self->pdata->macaddr, - self->pdata->sdd_file, - self->pdata->have_5ghz); - - if (status) { - cw1200_spi_irq_unsubscribe(self); - cw1200_spi_off(plat_data); - } - - return status; -} - -/* Disconnect Function to be called by SPI stack when device is disconnected */ -static int cw1200_spi_disconnect(struct spi_device *func) -{ - struct hwbus_priv *self = spi_get_drvdata(func); - - if (self) { - cw1200_spi_irq_unsubscribe(self); - if (self->core) { - cw1200_core_release(self->core); - self->core = NULL; - } - } - cw1200_spi_off(dev_get_platdata(&func->dev)); - - return 0; -} - -#ifdef CONFIG_PM -static int cw1200_spi_suspend(struct device *dev) -{ - struct hwbus_priv *self = spi_get_drvdata(to_spi_device(dev)); - - if (!cw1200_can_suspend(self->core)) - return -EAGAIN; - - /* XXX notify host that we have to keep CW1200 powered on? */ - return 0; -} - -static SIMPLE_DEV_PM_OPS(cw1200_pm_ops, cw1200_spi_suspend, NULL); - -#endif - -static struct spi_driver spi_driver = { - .probe = cw1200_spi_probe, - .remove = cw1200_spi_disconnect, - .driver = { - .name = "cw1200_wlan_spi", -#ifdef CONFIG_PM - .pm = &cw1200_pm_ops, -#endif - }, -}; - -module_spi_driver(spi_driver); -- cgit v1.2.3-54-g00ecf