Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: GPL-2.0-only
0002 /*
0003  * SPI interface.
0004  *
0005  * Copyright (c) 2017-2020, Silicon Laboratories, Inc.
0006  * Copyright (c) 2011, Sagrad Inc.
0007  * Copyright (c) 2010, ST-Ericsson
0008  */
0009 #include <linux/module.h>
0010 #include <linux/delay.h>
0011 #include <linux/gpio/consumer.h>
0012 #include <linux/spi/spi.h>
0013 #include <linux/interrupt.h>
0014 #include <linux/irq.h>
0015 #include <linux/of.h>
0016 
0017 #include "bus.h"
0018 #include "wfx.h"
0019 #include "hwio.h"
0020 #include "main.h"
0021 #include "bh.h"
0022 
0023 #define SET_WRITE 0x7FFF        /* usage: and operation */
0024 #define SET_READ 0x8000         /* usage: or operation */
0025 
0026 static const struct wfx_platform_data pdata_wf200 = {
0027     .file_fw = "wfx/wfm_wf200",
0028     .file_pds = "wfx/wf200.pds",
0029     .use_rising_clk = true,
0030 };
0031 
0032 static const struct wfx_platform_data pdata_brd4001a = {
0033     .file_fw = "wfx/wfm_wf200",
0034     .file_pds = "wfx/brd4001a.pds",
0035     .use_rising_clk = true,
0036 };
0037 
0038 static const struct wfx_platform_data pdata_brd8022a = {
0039     .file_fw = "wfx/wfm_wf200",
0040     .file_pds = "wfx/brd8022a.pds",
0041     .use_rising_clk = true,
0042 };
0043 
0044 static const struct wfx_platform_data pdata_brd8023a = {
0045     .file_fw = "wfx/wfm_wf200",
0046     .file_pds = "wfx/brd8023a.pds",
0047     .use_rising_clk = true,
0048 };
0049 
0050 struct wfx_spi_priv {
0051     struct spi_device *func;
0052     struct wfx_dev *core;
0053     struct gpio_desc *gpio_reset;
0054     bool need_swab;
0055 };
0056 
0057 /* The chip reads 16bits of data at time and place them directly into (little endian) CPU register.
0058  * So, the chip expects bytes order to be "B1 B0 B3 B2" (while LE is "B0 B1 B2 B3" and BE is
0059  * "B3 B2 B1 B0")
0060  *
0061  * A little endian host with bits_per_word == 16 should do the right job natively. The code below to
0062  * support big endian host and commonly used SPI 8bits.
0063  */
0064 static int wfx_spi_copy_from_io(void *priv, unsigned int addr, void *dst, size_t count)
0065 {
0066     struct wfx_spi_priv *bus = priv;
0067     u16 regaddr = (addr << 12) | (count / 2) | SET_READ;
0068     struct spi_message m;
0069     struct spi_transfer t_addr = {
0070         .tx_buf = &regaddr,
0071         .len = sizeof(regaddr),
0072     };
0073     struct spi_transfer t_msg = {
0074         .rx_buf = dst,
0075         .len = count,
0076     };
0077     u16 *dst16 = dst;
0078     int ret, i;
0079 
0080     WARN(count % 2, "buffer size must be a multiple of 2");
0081 
0082     cpu_to_le16s(&regaddr);
0083     if (bus->need_swab)
0084         swab16s(&regaddr);
0085 
0086     spi_message_init(&m);
0087     spi_message_add_tail(&t_addr, &m);
0088     spi_message_add_tail(&t_msg, &m);
0089     ret = spi_sync(bus->func, &m);
0090 
0091     if (bus->need_swab && addr == WFX_REG_CONFIG)
0092         for (i = 0; i < count / 2; i++)
0093             swab16s(&dst16[i]);
0094     return ret;
0095 }
0096 
0097 static int wfx_spi_copy_to_io(void *priv, unsigned int addr, const void *src, size_t count)
0098 {
0099     struct wfx_spi_priv *bus = priv;
0100     u16 regaddr = (addr << 12) | (count / 2);
0101     /* FIXME: use a bounce buffer */
0102     u16 *src16 = (void *)src;
0103     int ret, i;
0104     struct spi_message m;
0105     struct spi_transfer t_addr = {
0106         .tx_buf = &regaddr,
0107         .len = sizeof(regaddr),
0108     };
0109     struct spi_transfer t_msg = {
0110         .tx_buf = src,
0111         .len = count,
0112     };
0113 
0114     WARN(count % 2, "buffer size must be a multiple of 2");
0115     WARN(regaddr & SET_READ, "bad addr or size overflow");
0116 
0117     cpu_to_le16s(&regaddr);
0118 
0119     /* Register address and CONFIG content always use 16bit big endian
0120      * ("BADC" order)
0121      */
0122     if (bus->need_swab)
0123         swab16s(&regaddr);
0124     if (bus->need_swab && addr == WFX_REG_CONFIG)
0125         for (i = 0; i < count / 2; i++)
0126             swab16s(&src16[i]);
0127 
0128     spi_message_init(&m);
0129     spi_message_add_tail(&t_addr, &m);
0130     spi_message_add_tail(&t_msg, &m);
0131     ret = spi_sync(bus->func, &m);
0132 
0133     if (bus->need_swab && addr == WFX_REG_CONFIG)
0134         for (i = 0; i < count / 2; i++)
0135             swab16s(&src16[i]);
0136     return ret;
0137 }
0138 
0139 static void wfx_spi_lock(void *priv)
0140 {
0141 }
0142 
0143 static void wfx_spi_unlock(void *priv)
0144 {
0145 }
0146 
0147 static irqreturn_t wfx_spi_irq_handler(int irq, void *priv)
0148 {
0149     struct wfx_spi_priv *bus = priv;
0150 
0151     wfx_bh_request_rx(bus->core);
0152     return IRQ_HANDLED;
0153 }
0154 
0155 static int wfx_spi_irq_subscribe(void *priv)
0156 {
0157     struct wfx_spi_priv *bus = priv;
0158     u32 flags;
0159 
0160     flags = irq_get_trigger_type(bus->func->irq);
0161     if (!flags)
0162         flags = IRQF_TRIGGER_HIGH;
0163     flags |= IRQF_ONESHOT;
0164     return devm_request_threaded_irq(&bus->func->dev, bus->func->irq, NULL,
0165                      wfx_spi_irq_handler, flags, "wfx", bus);
0166 }
0167 
0168 static int wfx_spi_irq_unsubscribe(void *priv)
0169 {
0170     struct wfx_spi_priv *bus = priv;
0171 
0172     devm_free_irq(&bus->func->dev, bus->func->irq, bus);
0173     return 0;
0174 }
0175 
0176 static size_t wfx_spi_align_size(void *priv, size_t size)
0177 {
0178     /* Most of SPI controllers avoid DMA if buffer size is not 32bit aligned */
0179     return ALIGN(size, 4);
0180 }
0181 
0182 static const struct wfx_hwbus_ops wfx_spi_hwbus_ops = {
0183     .copy_from_io    = wfx_spi_copy_from_io,
0184     .copy_to_io      = wfx_spi_copy_to_io,
0185     .irq_subscribe   = wfx_spi_irq_subscribe,
0186     .irq_unsubscribe = wfx_spi_irq_unsubscribe,
0187     .lock            = wfx_spi_lock,
0188     .unlock          = wfx_spi_unlock,
0189     .align_size      = wfx_spi_align_size,
0190 };
0191 
0192 static int wfx_spi_probe(struct spi_device *func)
0193 {
0194     struct wfx_platform_data *pdata;
0195     struct wfx_spi_priv *bus;
0196     int ret;
0197 
0198     if (!func->bits_per_word)
0199         func->bits_per_word = 16;
0200     ret = spi_setup(func);
0201     if (ret)
0202         return ret;
0203     pdata = (struct wfx_platform_data *)spi_get_device_id(func)->driver_data;
0204     if (!pdata) {
0205         dev_err(&func->dev, "unable to retrieve driver data (please report)\n");
0206         return -ENODEV;
0207     }
0208 
0209     /* Trace below is also displayed by spi_setup() if compiled with DEBUG */
0210     dev_dbg(&func->dev, "SPI params: CS=%d, mode=%d bits/word=%d speed=%d\n",
0211         func->chip_select, func->mode, func->bits_per_word, func->max_speed_hz);
0212     if (func->bits_per_word != 16 && func->bits_per_word != 8)
0213         dev_warn(&func->dev, "unusual bits/word value: %d\n", func->bits_per_word);
0214     if (func->max_speed_hz > 50000000)
0215         dev_warn(&func->dev, "%dHz is a very high speed\n", func->max_speed_hz);
0216 
0217     bus = devm_kzalloc(&func->dev, sizeof(*bus), GFP_KERNEL);
0218     if (!bus)
0219         return -ENOMEM;
0220     bus->func = func;
0221     if (func->bits_per_word == 8 || IS_ENABLED(CONFIG_CPU_BIG_ENDIAN))
0222         bus->need_swab = true;
0223     spi_set_drvdata(func, bus);
0224 
0225     bus->gpio_reset = devm_gpiod_get_optional(&func->dev, "reset", GPIOD_OUT_LOW);
0226     if (IS_ERR(bus->gpio_reset))
0227         return PTR_ERR(bus->gpio_reset);
0228     if (!bus->gpio_reset) {
0229         dev_warn(&func->dev, "gpio reset is not defined, trying to load firmware anyway\n");
0230     } else {
0231         gpiod_set_consumer_name(bus->gpio_reset, "wfx reset");
0232         gpiod_set_value_cansleep(bus->gpio_reset, 1);
0233         usleep_range(100, 150);
0234         gpiod_set_value_cansleep(bus->gpio_reset, 0);
0235         usleep_range(2000, 2500);
0236     }
0237 
0238     bus->core = wfx_init_common(&func->dev, pdata, &wfx_spi_hwbus_ops, bus);
0239     if (!bus->core)
0240         return -EIO;
0241 
0242     return wfx_probe(bus->core);
0243 }
0244 
0245 static void wfx_spi_remove(struct spi_device *func)
0246 {
0247     struct wfx_spi_priv *bus = spi_get_drvdata(func);
0248 
0249     wfx_release(bus->core);
0250 }
0251 
0252 /* For dynamic driver binding, kernel does not use OF to match driver. It only
0253  * use modalias and modalias is a copy of 'compatible' DT node with vendor
0254  * stripped.
0255  */
0256 static const struct spi_device_id wfx_spi_id[] = {
0257     { "wf200",    (kernel_ulong_t)&pdata_wf200 },
0258     { "brd4001a", (kernel_ulong_t)&pdata_brd4001a },
0259     { "brd8022a", (kernel_ulong_t)&pdata_brd8022a },
0260     { "brd8023a", (kernel_ulong_t)&pdata_brd8023a },
0261     { },
0262 };
0263 MODULE_DEVICE_TABLE(spi, wfx_spi_id);
0264 
0265 #ifdef CONFIG_OF
0266 static const struct of_device_id wfx_spi_of_match[] = {
0267     { .compatible = "silabs,wf200" },
0268     { .compatible = "silabs,brd4001a" },
0269     { .compatible = "silabs,brd8022a" },
0270     { .compatible = "silabs,brd8023a" },
0271     { },
0272 };
0273 MODULE_DEVICE_TABLE(of, wfx_spi_of_match);
0274 #endif
0275 
0276 struct spi_driver wfx_spi_driver = {
0277     .driver = {
0278         .name = "wfx-spi",
0279         .of_match_table = of_match_ptr(wfx_spi_of_match),
0280     },
0281     .id_table = wfx_spi_id,
0282     .probe = wfx_spi_probe,
0283     .remove = wfx_spi_remove,
0284 };