linux/drivers/staging/wfx/bus_spi.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 * SPI interface.
   4 *
   5 * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
   6 * Copyright (c) 2011, Sagrad Inc.
   7 * Copyright (c) 2010, ST-Ericsson
   8 */
   9#include <linux/module.h>
  10#include <linux/delay.h>
  11#include <linux/gpio/consumer.h>
  12#include <linux/spi/spi.h>
  13#include <linux/interrupt.h>
  14#include <linux/irq.h>
  15#include <linux/of.h>
  16
  17#include "bus.h"
  18#include "wfx.h"
  19#include "hwio.h"
  20#include "main.h"
  21#include "bh.h"
  22
  23#define SET_WRITE 0x7FFF        /* usage: and operation */
  24#define SET_READ 0x8000         /* usage: or operation */
  25
  26#define WFX_RESET_INVERTED 1
  27
  28static const struct wfx_platform_data wfx_spi_pdata = {
  29        .file_fw = "wfm_wf200",
  30        .file_pds = "wf200.pds",
  31        .use_rising_clk = true,
  32};
  33
  34struct wfx_spi_priv {
  35        struct spi_device *func;
  36        struct wfx_dev *core;
  37        struct gpio_desc *gpio_reset;
  38        bool need_swab;
  39};
  40
  41/*
  42 * WFx chip read data 16bits at time and place them directly into (little
  43 * endian) CPU register. So, chip expect byte order like "B1 B0 B3 B2" (while
  44 * LE is "B0 B1 B2 B3" and BE is "B3 B2 B1 B0")
  45 *
  46 * A little endian host with bits_per_word == 16 should do the right job
  47 * natively. The code below to support big endian host and commonly used SPI
  48 * 8bits.
  49 */
  50static int wfx_spi_copy_from_io(void *priv, unsigned int addr,
  51                                void *dst, size_t count)
  52{
  53        struct wfx_spi_priv *bus = priv;
  54        u16 regaddr = (addr << 12) | (count / 2) | SET_READ;
  55        struct spi_message      m;
  56        struct spi_transfer     t_addr = {
  57                .tx_buf         = &regaddr,
  58                .len            = sizeof(regaddr),
  59        };
  60        struct spi_transfer     t_msg = {
  61                .rx_buf         = dst,
  62                .len            = count,
  63        };
  64        u16 *dst16 = dst;
  65        int ret, i;
  66
  67        WARN(count % 2, "buffer size must be a multiple of 2");
  68
  69        cpu_to_le16s(&regaddr);
  70        if (bus->need_swab)
  71                swab16s(&regaddr);
  72
  73        spi_message_init(&m);
  74        spi_message_add_tail(&t_addr, &m);
  75        spi_message_add_tail(&t_msg, &m);
  76        ret = spi_sync(bus->func, &m);
  77
  78        if (bus->need_swab && addr == WFX_REG_CONFIG)
  79                for (i = 0; i < count / 2; i++)
  80                        swab16s(&dst16[i]);
  81        return ret;
  82}
  83
  84static int wfx_spi_copy_to_io(void *priv, unsigned int addr,
  85                              const void *src, size_t count)
  86{
  87        struct wfx_spi_priv *bus = priv;
  88        u16 regaddr = (addr << 12) | (count / 2);
  89        // FIXME: use a bounce buffer
  90        u16 *src16 = (void *)src;
  91        int ret, i;
  92        struct spi_message      m;
  93        struct spi_transfer     t_addr = {
  94                .tx_buf         = &regaddr,
  95                .len            = sizeof(regaddr),
  96        };
  97        struct spi_transfer     t_msg = {
  98                .tx_buf         = src,
  99                .len            = count,
 100        };
 101
 102        WARN(count % 2, "buffer size must be a multiple of 2");
 103        WARN(regaddr & SET_READ, "bad addr or size overflow");
 104
 105        cpu_to_le16s(&regaddr);
 106
 107        // Register address and CONFIG content always use 16bit big endian
 108        // ("BADC" order)
 109        if (bus->need_swab)
 110                swab16s(&regaddr);
 111        if (bus->need_swab && addr == WFX_REG_CONFIG)
 112                for (i = 0; i < count / 2; i++)
 113                        swab16s(&src16[i]);
 114
 115        spi_message_init(&m);
 116        spi_message_add_tail(&t_addr, &m);
 117        spi_message_add_tail(&t_msg, &m);
 118        ret = spi_sync(bus->func, &m);
 119
 120        if (bus->need_swab && addr == WFX_REG_CONFIG)
 121                for (i = 0; i < count / 2; i++)
 122                        swab16s(&src16[i]);
 123        return ret;
 124}
 125
 126static void wfx_spi_lock(void *priv)
 127{
 128}
 129
 130static void wfx_spi_unlock(void *priv)
 131{
 132}
 133
 134static irqreturn_t wfx_spi_irq_handler(int irq, void *priv)
 135{
 136        struct wfx_spi_priv *bus = priv;
 137
 138        wfx_bh_request_rx(bus->core);
 139        return IRQ_HANDLED;
 140}
 141
 142static int wfx_spi_irq_subscribe(void *priv)
 143{
 144        struct wfx_spi_priv *bus = priv;
 145        u32 flags;
 146
 147        flags = irq_get_trigger_type(bus->func->irq);
 148        if (!flags)
 149                flags = IRQF_TRIGGER_HIGH;
 150        flags |= IRQF_ONESHOT;
 151        return devm_request_threaded_irq(&bus->func->dev, bus->func->irq, NULL,
 152                                         wfx_spi_irq_handler, IRQF_ONESHOT,
 153                                         "wfx", bus);
 154}
 155
 156static int wfx_spi_irq_unsubscribe(void *priv)
 157{
 158        struct wfx_spi_priv *bus = priv;
 159
 160        devm_free_irq(&bus->func->dev, bus->func->irq, bus);
 161        return 0;
 162}
 163
 164static size_t wfx_spi_align_size(void *priv, size_t size)
 165{
 166        // Most of SPI controllers avoid DMA if buffer size is not 32bit aligned
 167        return ALIGN(size, 4);
 168}
 169
 170static const struct hwbus_ops wfx_spi_hwbus_ops = {
 171        .copy_from_io = wfx_spi_copy_from_io,
 172        .copy_to_io = wfx_spi_copy_to_io,
 173        .irq_subscribe = wfx_spi_irq_subscribe,
 174        .irq_unsubscribe = wfx_spi_irq_unsubscribe,
 175        .lock                   = wfx_spi_lock,
 176        .unlock                 = wfx_spi_unlock,
 177        .align_size             = wfx_spi_align_size,
 178};
 179
 180static int wfx_spi_probe(struct spi_device *func)
 181{
 182        struct wfx_spi_priv *bus;
 183        int ret;
 184
 185        if (!func->bits_per_word)
 186                func->bits_per_word = 16;
 187        ret = spi_setup(func);
 188        if (ret)
 189                return ret;
 190        // Trace below is also displayed by spi_setup() if compiled with DEBUG
 191        dev_dbg(&func->dev, "SPI params: CS=%d, mode=%d bits/word=%d speed=%d\n",
 192                func->chip_select, func->mode, func->bits_per_word,
 193                func->max_speed_hz);
 194        if (func->bits_per_word != 16 && func->bits_per_word != 8)
 195                dev_warn(&func->dev, "unusual bits/word value: %d\n",
 196                         func->bits_per_word);
 197        if (func->max_speed_hz > 50000000)
 198                dev_warn(&func->dev, "%dHz is a very high speed\n",
 199                         func->max_speed_hz);
 200
 201        bus = devm_kzalloc(&func->dev, sizeof(*bus), GFP_KERNEL);
 202        if (!bus)
 203                return -ENOMEM;
 204        bus->func = func;
 205        if (func->bits_per_word == 8 || IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
 206                bus->need_swab = true;
 207        spi_set_drvdata(func, bus);
 208
 209        bus->gpio_reset = devm_gpiod_get_optional(&func->dev, "reset",
 210                                                  GPIOD_OUT_LOW);
 211        if (IS_ERR(bus->gpio_reset))
 212                return PTR_ERR(bus->gpio_reset);
 213        if (!bus->gpio_reset) {
 214                dev_warn(&func->dev,
 215                         "gpio reset is not defined, trying to load firmware anyway\n");
 216        } else {
 217                gpiod_set_consumer_name(bus->gpio_reset, "wfx reset");
 218                if (spi_get_device_id(func)->driver_data & WFX_RESET_INVERTED)
 219                        gpiod_toggle_active_low(bus->gpio_reset);
 220                gpiod_set_value_cansleep(bus->gpio_reset, 1);
 221                usleep_range(100, 150);
 222                gpiod_set_value_cansleep(bus->gpio_reset, 0);
 223                usleep_range(2000, 2500);
 224        }
 225
 226        bus->core = wfx_init_common(&func->dev, &wfx_spi_pdata,
 227                                    &wfx_spi_hwbus_ops, bus);
 228        if (!bus->core)
 229                return -EIO;
 230
 231        return wfx_probe(bus->core);
 232}
 233
 234static int wfx_spi_remove(struct spi_device *func)
 235{
 236        struct wfx_spi_priv *bus = spi_get_drvdata(func);
 237
 238        wfx_release(bus->core);
 239        return 0;
 240}
 241
 242/*
 243 * For dynamic driver binding, kernel does not use OF to match driver. It only
 244 * use modalias and modalias is a copy of 'compatible' DT node with vendor
 245 * stripped.
 246 */
 247static const struct spi_device_id wfx_spi_id[] = {
 248        { "wfx-spi", WFX_RESET_INVERTED },
 249        { "wf200", 0 },
 250        { },
 251};
 252MODULE_DEVICE_TABLE(spi, wfx_spi_id);
 253
 254#ifdef CONFIG_OF
 255static const struct of_device_id wfx_spi_of_match[] = {
 256        { .compatible = "silabs,wfx-spi", .data = (void *)WFX_RESET_INVERTED },
 257        { .compatible = "silabs,wf200" },
 258        { },
 259};
 260MODULE_DEVICE_TABLE(of, wfx_spi_of_match);
 261#endif
 262
 263struct spi_driver wfx_spi_driver = {
 264        .driver = {
 265                .name = "wfx-spi",
 266                .of_match_table = of_match_ptr(wfx_spi_of_match),
 267        },
 268        .id_table = wfx_spi_id,
 269        .probe = wfx_spi_probe,
 270        .remove = wfx_spi_remove,
 271};
 272