^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /****************************************************************************
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) * Driver for the IFX 6x60 spi modem.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Copyright (C) 2008 Option International
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (C) 2008 Filip Aben <f.aben@option.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Denis Joseph Barrow <d.barow@option.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Jan Dumon <j.dumon@option.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Copyright (C) 2009, 2010 Intel Corp
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * Russ Gorby <russ.gorby@intel.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * Driver modified by Intel from Option gtm501l_spi.c
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * Notes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * o The driver currently assumes a single device only. If you need to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) * change this then look for saved_ifx_dev and add a device lookup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * o The driver is intended to be big-endian safe but has never been
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * tested that way (no suitable hardware). There are a couple of FIXME
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * notes by areas that may need addressing
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * o Some of the GPIO naming/setup assumptions may need revisiting if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * you need to use this driver for another platform.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) *****************************************************************************/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) #include <linux/dma-mapping.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #include <linux/termios.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #include <linux/tty.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #include <linux/device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #include <linux/spi/spi.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #include <linux/kfifo.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #include <linux/tty_flip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #include <linux/timer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #include <linux/serial.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #include <linux/interrupt.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) #include <linux/irq.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #include <linux/rfkill.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #include <linux/fs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #include <linux/ip.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #include <linux/dmapool.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #include <linux/gpio/consumer.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #include <linux/sched.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #include <linux/time.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #include <linux/wait.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #include <linux/pm.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) #include <linux/pm_runtime.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #include <linux/spi/ifx_modem.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/delay.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/reboot.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #include "ifx6x60.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define IFX_SPI_MORE_MASK 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define IFX_SPI_MORE_BIT 4 /* bit position in u8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define IFX_SPI_CTS_BIT 6 /* bit position in u8 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define IFX_SPI_MODE SPI_MODE_1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define IFX_SPI_TTY_ID 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define IFX_SPI_TIMEOUT_SEC 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define IFX_SPI_HEADER_0 (-1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define IFX_SPI_HEADER_F (-2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define PO_POST_DELAY 200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) /* forward reference */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) static int ifx_modem_reboot_callback(struct notifier_block *nfb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) unsigned long event, void *data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* local variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static int spi_bpw = 16; /* 8, 16 or 32 bit word length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) static struct tty_driver *tty_drv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) static struct ifx_spi_device *saved_ifx_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) static struct lock_class_key ifx_spi_key;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) static struct notifier_block ifx_modem_reboot_notifier_block = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) .notifier_call = ifx_modem_reboot_callback,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) static int ifx_modem_power_off(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) gpiod_set_value(ifx_dev->gpio.pmu_reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) msleep(PO_POST_DELAY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) static int ifx_modem_reboot_callback(struct notifier_block *nfb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) unsigned long event, void *data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) if (saved_ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) ifx_modem_power_off(saved_ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) pr_warn("no ifx modem active;\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) return NOTIFY_OK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) /* GPIO/GPE settings */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) * mrdy_set_high - set MRDY GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) * @ifx: device we are controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) static inline void mrdy_set_high(struct ifx_spi_device *ifx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) gpiod_set_value(ifx->gpio.mrdy, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) * mrdy_set_low - clear MRDY GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) * @ifx: device we are controlling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) static inline void mrdy_set_low(struct ifx_spi_device *ifx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) gpiod_set_value(ifx->gpio.mrdy, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) * ifx_spi_power_state_set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) * @ifx_dev: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) * @val: bits to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) * Set bit in power status and signal power system if status becomes non-0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ifx_spi_power_state_set(struct ifx_spi_device *ifx_dev, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) spin_lock_irqsave(&ifx_dev->power_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) * if power status is already non-0, just update, else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) * tell power system
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) if (!ifx_dev->power_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) pm_runtime_get(&ifx_dev->spi_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) ifx_dev->power_status |= val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) spin_unlock_irqrestore(&ifx_dev->power_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) * ifx_spi_power_state_clear - clear power bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) * @ifx_dev: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) * @val: bits to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) * clear bit in power status and signal power system if status becomes 0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) ifx_spi_power_state_clear(struct ifx_spi_device *ifx_dev, unsigned char val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) spin_lock_irqsave(&ifx_dev->power_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) if (ifx_dev->power_status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) ifx_dev->power_status &= ~val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) if (!ifx_dev->power_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) pm_runtime_put(&ifx_dev->spi_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) spin_unlock_irqrestore(&ifx_dev->power_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * swap_buf_8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) * @buf: our buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * @len : number of bytes (not words) in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) * @end: end of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) * Swap the contents of a buffer into big endian format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static inline void swap_buf_8(unsigned char *buf, int len, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) /* don't swap buffer if SPI word width is 8 bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) * swap_buf_16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) * @buf: our buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) * @len : number of bytes (not words) in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) * @end: end of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * Swap the contents of a buffer into big endian format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) static inline void swap_buf_16(unsigned char *buf, int len, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) u16 *buf_16 = (u16 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) len = ((len + 1) >> 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) if ((void *)&buf_16[len] > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) pr_err("swap_buf_16: swap exceeds boundary (%p > %p)!",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) &buf_16[len], end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) for (n = 0; n < len; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) *buf_16 = cpu_to_be16(*buf_16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) buf_16++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) * swap_buf_32
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) * @buf: our buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * @len : number of bytes (not words) in the buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) * @end: end of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) * Swap the contents of a buffer into big endian format
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) static inline void swap_buf_32(unsigned char *buf, int len, void *end)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) int n;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) u32 *buf_32 = (u32 *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) len = (len + 3) >> 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) if ((void *)&buf_32[len] > end) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) pr_err("swap_buf_32: swap exceeds boundary (%p > %p)!\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) &buf_32[len], end);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) for (n = 0; n < len; n++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) *buf_32 = cpu_to_be32(*buf_32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) buf_32++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) * mrdy_assert - assert MRDY line
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * @ifx_dev: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * Assert mrdy and set timer to wait for SRDY interrupt, if SRDY is low
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * now.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) * FIXME: Can SRDY even go high as we are running this code ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static void mrdy_assert(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) int val = gpiod_get_value(ifx_dev->gpio.srdy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) if (!val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) if (!test_and_set_bit(IFX_SPI_STATE_TIMER_PENDING,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) &ifx_dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) mod_timer(&ifx_dev->spi_timer,jiffies + IFX_SPI_TIMEOUT_SEC*HZ);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) ifx_spi_power_state_set(ifx_dev, IFX_SPI_POWER_DATA_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) mrdy_set_high(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) * ifx_spi_timeout - SPI timeout
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) * @t: timer in our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) * The SPI has timed out: hang up the tty. Users will then see a hangup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) * and error events.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) static void ifx_spi_timeout(struct timer_list *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) struct ifx_spi_device *ifx_dev = from_timer(ifx_dev, t, spi_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) dev_warn(&ifx_dev->spi_dev->dev, "*** SPI Timeout ***");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) tty_port_tty_hangup(&ifx_dev->tty_port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) mrdy_set_low(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) /* char/tty operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) * ifx_spi_tiocmget - get modem lines
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) * @tty: our tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) * Map the signal state into Linux modem flags and report the value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) * in Linux terms
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) static int ifx_spi_tiocmget(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) unsigned int value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) value =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) (test_bit(IFX_SPI_RTS, &ifx_dev->signal_state) ? TIOCM_RTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) (test_bit(IFX_SPI_DTR, &ifx_dev->signal_state) ? TIOCM_DTR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) (test_bit(IFX_SPI_CTS, &ifx_dev->signal_state) ? TIOCM_CTS : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) (test_bit(IFX_SPI_DSR, &ifx_dev->signal_state) ? TIOCM_DSR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) (test_bit(IFX_SPI_DCD, &ifx_dev->signal_state) ? TIOCM_CAR : 0) |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) (test_bit(IFX_SPI_RI, &ifx_dev->signal_state) ? TIOCM_RNG : 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) return value;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) * ifx_spi_tiocmset - set modem bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * @tty: the tty structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * @set: bits to set
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @clear: bits to clear
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * The IFX6x60 only supports DTR and RTS. Set them accordingly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * and flag that an update to the modem is needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) * FIXME: do we need to kick the tranfers when we do this ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static int ifx_spi_tiocmset(struct tty_struct *tty,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) unsigned int set, unsigned int clear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if (set & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) set_bit(IFX_SPI_RTS, &ifx_dev->signal_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) if (set & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) set_bit(IFX_SPI_DTR, &ifx_dev->signal_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (clear & TIOCM_RTS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) clear_bit(IFX_SPI_RTS, &ifx_dev->signal_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) if (clear & TIOCM_DTR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) clear_bit(IFX_SPI_DTR, &ifx_dev->signal_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) set_bit(IFX_SPI_UPDATE, &ifx_dev->signal_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) * ifx_spi_open - called on tty open
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) * @tty: our tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) * @filp: file handle being associated with the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) * Open the tty interface. We let the tty_port layer do all the work
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) * for us.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) * FIXME: Remove single device assumption and saved_ifx_dev
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) static int ifx_spi_open(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) return tty_port_open(&saved_ifx_dev->tty_port, tty, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) * ifx_spi_close - called when our tty closes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) * @tty: the tty being closed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) * @filp: the file handle being closed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) * Perform the close of the tty. We use the tty_port layer to do all
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) * our hard work.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) static void ifx_spi_close(struct tty_struct *tty, struct file *filp)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) tty_port_close(&ifx_dev->tty_port, tty, filp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) /* FIXME: should we do an ifx_spi_reset here ? */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) * ifx_decode_spi_header - decode received header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) * @buffer: the received data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * @length: decoded length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) * @more: decoded more flag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) * @received_cts: status of cts we received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * Note how received_cts is handled -- if header is all F it is left
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) * the same as it was, if header is all 0 it is set to 0 otherwise it is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * taken from the incoming header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * FIXME: endianness
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) static int ifx_spi_decode_spi_header(unsigned char *buffer, int *length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) unsigned char *more, unsigned char *received_cts)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) u16 h1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) u16 h2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) u16 *in_buffer = (u16 *)buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) h1 = *in_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) h2 = *(in_buffer+1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) if (h1 == 0 && h2 == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) *received_cts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) *more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) return IFX_SPI_HEADER_0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) } else if (h1 == 0xffff && h2 == 0xffff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) *more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) /* spi_slave_cts remains as it was */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) return IFX_SPI_HEADER_F;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) *length = h1 & 0xfff; /* upper bits of byte are flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) *more = (buffer[1] >> IFX_SPI_MORE_BIT) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) *received_cts = (buffer[3] >> IFX_SPI_CTS_BIT) & 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) * ifx_setup_spi_header - set header fields
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) * @txbuffer: pointer to start of SPI buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) * @tx_count: bytes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) * @more: indicate if more to follow
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) * Format up an SPI header for a transfer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) * FIXME: endianness?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) static void ifx_spi_setup_spi_header(unsigned char *txbuffer, int tx_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) unsigned char more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) *(u16 *)(txbuffer) = tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) *(u16 *)(txbuffer+2) = IFX_SPI_PAYLOAD_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) txbuffer[1] |= (more << IFX_SPI_MORE_BIT) & IFX_SPI_MORE_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) * ifx_spi_prepare_tx_buffer - prepare transmit frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) * @ifx_dev: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) * The transmit buffr needs a header and various other bits of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) * information followed by as much data as we can pull from the FIFO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) * and transfer. This function formats up a suitable buffer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422) * ifx_dev->tx_buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * FIXME: performance - should we wake the tty when the queue is half
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) * empty ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) static int ifx_spi_prepare_tx_buffer(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) int temp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) int queue_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) int tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) unsigned char *tx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) tx_buffer = ifx_dev->tx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) /* make room for required SPI header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) tx_buffer += IFX_SPI_HEADER_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) tx_count = IFX_SPI_HEADER_OVERHEAD;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* clear to signal no more data if this turns out to be the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * last buffer sent in a sequence */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) ifx_dev->spi_more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) /* if modem cts is set, just send empty buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) if (!ifx_dev->spi_slave_cts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) /* see if there's tx data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) queue_length = kfifo_len(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) if (queue_length != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) /* data to mux -- see if there's room for it */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) temp_count = min(queue_length, IFX_SPI_PAYLOAD_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) temp_count = kfifo_out_locked(&ifx_dev->tx_fifo,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) tx_buffer, temp_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) &ifx_dev->fifo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) /* update buffer pointer and data count in message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) tx_buffer += temp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) tx_count += temp_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) if (temp_count == queue_length)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) /* poke port to get more data */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) tty_port_tty_wakeup(&ifx_dev->tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) else /* more data in port, use next SPI message */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) ifx_dev->spi_more = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) /* have data and info for header -- set up SPI header in buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) /* spi header needs payload size, not entire buffer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) ifx_spi_setup_spi_header(ifx_dev->tx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) tx_count-IFX_SPI_HEADER_OVERHEAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) ifx_dev->spi_more);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) /* swap actual data in the buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) ifx_dev->swap_buf((ifx_dev->tx_buffer), tx_count,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) &ifx_dev->tx_buffer[IFX_SPI_TRANSFER_SIZE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) return tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) * ifx_spi_write - line discipline write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) * @tty: our tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) * @buf: pointer to buffer to write (kernel space)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) * @count: size of buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) * Write the characters we have been given into the FIFO. If the device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) * is not active then activate it, when the SRDY line is asserted back
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) * this will commence I/O
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) static int ifx_spi_write(struct tty_struct *tty, const unsigned char *buf,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) int count)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) unsigned char *tmp_buf = (unsigned char *)buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492) bool is_fifo_empty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) int tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) spin_lock_irqsave(&ifx_dev->fifo_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) is_fifo_empty = kfifo_is_empty(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) tx_count = kfifo_in(&ifx_dev->tx_fifo, tmp_buf, count);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) spin_unlock_irqrestore(&ifx_dev->fifo_lock, flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) if (is_fifo_empty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) mrdy_assert(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) return tx_count;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) * ifx_spi_chars_in_buffer - line discipline helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) * @tty: our tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) * Report how much data we can accept before we drop bytes. As we use
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) * a simple FIFO this is nice and easy.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) static int ifx_spi_write_room(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) return IFX_SPI_FIFO_SIZE - kfifo_len(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * ifx_spi_chars_in_buffer - line discipline helper
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) * @tty: our tty device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) * Report how many characters we have buffered. In our case this is the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) * number of bytes sitting in our transmit FIFO.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) static int ifx_spi_chars_in_buffer(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) return kfifo_len(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * ifx_port_hangup
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) * @tty: our tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * tty port hang up. Called when tty_hangup processing is invoked either
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) * by loss of carrier, or by software (eg vhangup). Serialized against
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) * activate/shutdown by the tty layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) static void ifx_spi_hangup(struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) struct ifx_spi_device *ifx_dev = tty->driver_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) tty_port_hangup(&ifx_dev->tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) * ifx_port_activate
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) * @port: our tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) * tty port activate method - called for first open. Serialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) * with hangup and shutdown by the tty layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) static int ifx_port_activate(struct tty_port *port, struct tty_struct *tty)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) struct ifx_spi_device *ifx_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) container_of(port, struct ifx_spi_device, tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* clear any old data; can't do this in 'close' */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) kfifo_reset(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) /* clear any flag which may be set in port shutdown procedure */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) /* put port data into this tty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) tty->driver_data = ifx_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) /* allows flip string push from int context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) port->low_latency = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) /* set flag to allows data transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571) set_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) * ifx_port_shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * @port: our tty port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) * tty port shutdown method - called for last port close. Serialized
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) * with hangup and activate by the tty layer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) static void ifx_port_shutdown(struct tty_port *port)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) struct ifx_spi_device *ifx_dev =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) container_of(port, struct ifx_spi_device, tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) clear_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) mrdy_set_low(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) del_timer(&ifx_dev->spi_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) tasklet_kill(&ifx_dev->io_work_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) static const struct tty_port_operations ifx_tty_port_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) .activate = ifx_port_activate,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) .shutdown = ifx_port_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) static const struct tty_operations ifx_spi_serial_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) .open = ifx_spi_open,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) .close = ifx_spi_close,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) .write = ifx_spi_write,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) .hangup = ifx_spi_hangup,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) .write_room = ifx_spi_write_room,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) .chars_in_buffer = ifx_spi_chars_in_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) .tiocmget = ifx_spi_tiocmget,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) .tiocmset = ifx_spi_tiocmset,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) * ifx_spi_insert_fip_string - queue received data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) * @ifx_dev: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) * @chars: buffer we have received
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) * @size: number of chars reeived
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) * Queue bytes to the tty assuming the tty side is currently open. If
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) * not the discard the data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) static void ifx_spi_insert_flip_string(struct ifx_spi_device *ifx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) unsigned char *chars, size_t size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) tty_insert_flip_string(&ifx_dev->tty_port, chars, size);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) tty_flip_buffer_push(&ifx_dev->tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628) * ifx_spi_complete - SPI transfer completed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) * @ctx: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) * An SPI transfer has completed. Process any received data and kick off
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) * any further transmits we can commence.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634) static void ifx_spi_complete(void *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) struct ifx_spi_device *ifx_dev = ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) int length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) int actual_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639) unsigned char more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) unsigned char cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) int local_write_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) int queue_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) int srdy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) int decode_result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) mrdy_set_low(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) if (!ifx_dev->spi_msg.status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649) /* check header validity, get comm flags */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) ifx_dev->swap_buf(ifx_dev->rx_buffer, IFX_SPI_HEADER_OVERHEAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) &ifx_dev->rx_buffer[IFX_SPI_HEADER_OVERHEAD]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) decode_result = ifx_spi_decode_spi_header(ifx_dev->rx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) &length, &more, &cts);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (decode_result == IFX_SPI_HEADER_0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) dev_dbg(&ifx_dev->spi_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) "ignore input: invalid header 0");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) ifx_dev->spi_slave_cts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658) goto complete_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) } else if (decode_result == IFX_SPI_HEADER_F) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) dev_dbg(&ifx_dev->spi_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) "ignore input: invalid header F");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) goto complete_exit;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) ifx_dev->spi_slave_cts = cts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) actual_length = min((unsigned int)length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) ifx_dev->spi_msg.actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) ifx_dev->swap_buf(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) (ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) actual_length,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) &ifx_dev->rx_buffer[IFX_SPI_TRANSFER_SIZE]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) ifx_spi_insert_flip_string(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) ifx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) ifx_dev->rx_buffer + IFX_SPI_HEADER_OVERHEAD,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) (size_t)actual_length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679) dev_dbg(&ifx_dev->spi_dev->dev, "SPI transfer error %d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) ifx_dev->spi_msg.status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683) complete_exit:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) if (ifx_dev->write_pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) ifx_dev->write_pending = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) local_write_pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &(ifx_dev->flags));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) queue_length = kfifo_len(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) srdy = gpiod_get_value(ifx_dev->gpio.srdy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) if (!srdy)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694) ifx_spi_power_state_clear(ifx_dev, IFX_SPI_POWER_SRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) /* schedule output if there is more to do */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) if (test_and_clear_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) tasklet_schedule(&ifx_dev->io_work_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) if (more || ifx_dev->spi_more || queue_length > 0 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) local_write_pending) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) if (ifx_dev->spi_slave_cts) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) if (more)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704) mrdy_assert(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) mrdy_assert(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) * poke line discipline driver if any for more data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) * may or may not get more data to write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711) * for now, say not busy
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ifx_spi_power_state_clear(ifx_dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) IFX_SPI_POWER_DATA_PENDING);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) tty_port_tty_wakeup(&ifx_dev->tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) * ifx_spio_io - I/O tasklet
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) * @data: our SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) * Queue data for transmission if possible and then kick off the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) * transfer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) static void ifx_spi_io(struct tasklet_struct *t)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) int retval;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) struct ifx_spi_device *ifx_dev = from_tasklet(ifx_dev, t,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) io_work_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) if (!test_and_set_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) test_bit(IFX_SPI_STATE_IO_AVAILABLE, &ifx_dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) if (ifx_dev->gpio.unack_srdy_int_nb > 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736) ifx_dev->gpio.unack_srdy_int_nb--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) ifx_spi_prepare_tx_buffer(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) spi_message_init(&ifx_dev->spi_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) INIT_LIST_HEAD(&ifx_dev->spi_msg.queue);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) ifx_dev->spi_msg.context = ifx_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) ifx_dev->spi_msg.complete = ifx_spi_complete;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) /* set up our spi transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) /* note len is BYTES, not transfers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) ifx_dev->spi_xfer.len = IFX_SPI_TRANSFER_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) ifx_dev->spi_xfer.cs_change = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750) ifx_dev->spi_xfer.speed_hz = ifx_dev->spi_dev->max_speed_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) /* ifx_dev->spi_xfer.speed_hz = 390625; */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) ifx_dev->spi_xfer.bits_per_word =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) ifx_dev->spi_dev->bits_per_word;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) ifx_dev->spi_xfer.tx_buf = ifx_dev->tx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) ifx_dev->spi_xfer.rx_buf = ifx_dev->rx_buffer;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) * setup dma pointers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) if (ifx_dev->use_dma) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) ifx_dev->spi_msg.is_dma_mapped = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763) ifx_dev->tx_dma = ifx_dev->tx_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) ifx_dev->rx_dma = ifx_dev->rx_bus;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) ifx_dev->spi_xfer.tx_dma = ifx_dev->tx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766) ifx_dev->spi_xfer.rx_dma = ifx_dev->rx_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) ifx_dev->spi_msg.is_dma_mapped = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) ifx_dev->tx_dma = (dma_addr_t)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) ifx_dev->rx_dma = (dma_addr_t)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771) ifx_dev->spi_xfer.tx_dma = (dma_addr_t)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) ifx_dev->spi_xfer.rx_dma = (dma_addr_t)0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) spi_message_add_tail(&ifx_dev->spi_xfer, &ifx_dev->spi_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) /* Assert MRDY. This may have already been done by the write
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778) * routine.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) mrdy_assert(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782) retval = spi_async(ifx_dev->spi_dev, &ifx_dev->spi_msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) if (retval) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) tasklet_schedule(&ifx_dev->io_work_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) ifx_dev->write_pending = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) * ifx_spi_free_port - free up the tty side
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) * @ifx_dev: IFX device going away
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) * Unregister and free up a port when the device goes away
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799) static void ifx_spi_free_port(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) if (ifx_dev->tty_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) tty_unregister_device(tty_drv, ifx_dev->minor);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) tty_port_destroy(&ifx_dev->tty_port);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) kfifo_free(&ifx_dev->tx_fifo);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) * ifx_spi_create_port - create a new port
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) * @ifx_dev: our spi device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) * Allocate and initialise the tty port that goes with this interface
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) * and add it to the tty layer so that it can be opened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) static int ifx_spi_create_port(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) struct tty_port *pport = &ifx_dev->tty_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) spin_lock_init(&ifx_dev->fifo_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) lockdep_set_class_and_subclass(&ifx_dev->fifo_lock,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) &ifx_spi_key, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) if (kfifo_alloc(&ifx_dev->tx_fifo, IFX_SPI_FIFO_SIZE, GFP_KERNEL)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) tty_port_init(pport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) pport->ops = &ifx_tty_port_ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830) ifx_dev->minor = IFX_SPI_TTY_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) ifx_dev->tty_dev = tty_port_register_device(pport, tty_drv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) ifx_dev->minor, &ifx_dev->spi_dev->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) if (IS_ERR(ifx_dev->tty_dev)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) dev_dbg(&ifx_dev->spi_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) "%s: registering tty device failed", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) ret = PTR_ERR(ifx_dev->tty_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837) goto error_port;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) error_port:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842) tty_port_destroy(pport);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) ifx_spi_free_port(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) * ifx_spi_handle_srdy - handle SRDY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) * @ifx_dev: device asserting SRDY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) * Check our device state and see what we need to kick off when SRDY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853) * is asserted. This usually means killing the timer and firing off the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) * I/O processing.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) static void ifx_spi_handle_srdy(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) if (test_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) del_timer(&ifx_dev->spi_timer);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) clear_bit(IFX_SPI_STATE_TIMER_PENDING, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) ifx_spi_power_state_set(ifx_dev, IFX_SPI_POWER_SRDY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) if (!test_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) tasklet_schedule(&ifx_dev->io_work_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) set_bit(IFX_SPI_STATE_IO_READY, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) * ifx_spi_srdy_interrupt - SRDY asserted
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) * @irq: our IRQ number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) * @dev: our ifx device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) * The modem asserted SRDY. Handle the srdy event
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) static irqreturn_t ifx_spi_srdy_interrupt(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) struct ifx_spi_device *ifx_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) ifx_dev->gpio.unack_srdy_int_nb++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882) ifx_spi_handle_srdy(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) * ifx_spi_reset_interrupt - Modem has changed reset state
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) * @irq: interrupt number
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) * @dev: our device pointer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) * The modem has either entered or left reset state. Check the GPIO
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) * line to see which.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) * FIXME: review locking on MR_INPROGRESS versus
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) * parallel unsolicited reset/solicited reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897) static irqreturn_t ifx_spi_reset_interrupt(int irq, void *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) struct ifx_spi_device *ifx_dev = dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) int val = gpiod_get_value(ifx_dev->gpio.reset_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) int solreset = test_bit(MR_START, &ifx_dev->mdm_reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903) if (val == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) /* entered reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) set_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) if (!solreset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) /* unsolicited reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) tty_port_tty_hangup(&ifx_dev->tty_port, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) /* exited reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912) clear_bit(MR_INPROGRESS, &ifx_dev->mdm_reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) if (solreset) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) set_bit(MR_COMPLETE, &ifx_dev->mdm_reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) wake_up(&ifx_dev->mdm_reset_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) return IRQ_HANDLED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * ifx_spi_free_device - free device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) * @ifx_dev: device to free
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) * Free the IFX device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) static void ifx_spi_free_device(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) ifx_spi_free_port(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) dma_free_coherent(&ifx_dev->spi_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) IFX_SPI_TRANSFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) ifx_dev->tx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) ifx_dev->tx_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) dma_free_coherent(&ifx_dev->spi_dev->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) IFX_SPI_TRANSFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) ifx_dev->rx_buffer,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) ifx_dev->rx_bus);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) * ifx_spi_reset - reset modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) * @ifx_dev: modem to reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) * Perform a reset on the modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) static int ifx_spi_reset(struct ifx_spi_device *ifx_dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) * set up modem power, reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) * delays are required on some platforms for the modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) * to reset properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) set_bit(MR_START, &ifx_dev->mdm_reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) gpiod_set_value(ifx_dev->gpio.po, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) gpiod_set_value(ifx_dev->gpio.reset, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) msleep(25);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) gpiod_set_value(ifx_dev->gpio.reset, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) gpiod_set_value(ifx_dev->gpio.po, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) msleep(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) gpiod_set_value(ifx_dev->gpio.po, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964) ret = wait_event_timeout(ifx_dev->mdm_reset_wait,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) test_bit(MR_COMPLETE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) &ifx_dev->mdm_reset_state),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967) IFX_RESET_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (!ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) dev_warn(&ifx_dev->spi_dev->dev, "Modem reset timeout: (state:%lx)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) ifx_dev->mdm_reset_state);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) ifx_dev->mdm_reset_state = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) * ifx_spi_spi_probe - probe callback
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) * @spi: our possible matching SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) * Probe for a 6x60 modem on SPI bus. Perform any needed device and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981) * GPIO setup.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983) * FIXME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) * - Support for multiple devices
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) * - Split out MID specific GPIO handling eventually
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) static int ifx_spi_spi_probe(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) int srdy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) struct ifx_modem_platform_data *pl_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) struct ifx_spi_device *ifx_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994) struct device *dev = &spi->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) if (saved_ifx_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) dev_dbg(dev, "ignoring subsequent detection");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) pl_data = dev_get_platdata(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) if (!pl_data) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) dev_err(dev, "missing platform data!");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* initialize structure to hold our device variables */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) ifx_dev = kzalloc(sizeof(struct ifx_spi_device), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) if (!ifx_dev) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) dev_err(dev, "spi device allocation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) saved_ifx_dev = ifx_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) ifx_dev->spi_dev = spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) clear_bit(IFX_SPI_STATE_IO_IN_PROGRESS, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) spin_lock_init(&ifx_dev->write_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) spin_lock_init(&ifx_dev->power_lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) ifx_dev->power_status = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) timer_setup(&ifx_dev->spi_timer, ifx_spi_timeout, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) ifx_dev->modem = pl_data->modem_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) ifx_dev->use_dma = pl_data->use_dma;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) ifx_dev->max_hz = pl_data->max_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) /* initialize spi mode, etc */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) spi->max_speed_hz = ifx_dev->max_hz;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) spi->mode = IFX_SPI_MODE | (SPI_LOOP & spi->mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) spi->bits_per_word = spi_bpw;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) ret = spi_setup(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) dev_err(dev, "SPI setup wasn't successful %d", ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) kfree(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) return -ENODEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) /* init swap_buf function according to word width configuration */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) if (spi->bits_per_word == 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) ifx_dev->swap_buf = swap_buf_32;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) else if (spi->bits_per_word == 16)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) ifx_dev->swap_buf = swap_buf_16;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) ifx_dev->swap_buf = swap_buf_8;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) /* ensure SPI protocol flags are initialized to enable transfer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) ifx_dev->spi_more = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) ifx_dev->spi_slave_cts = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) /*initialize transfer and dma buffers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) ifx_dev->tx_buffer = dma_alloc_coherent(ifx_dev->spi_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) IFX_SPI_TRANSFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) &ifx_dev->tx_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) if (!ifx_dev->tx_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) dev_err(dev, "DMA-TX buffer allocation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) ifx_dev->rx_buffer = dma_alloc_coherent(ifx_dev->spi_dev->dev.parent,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) IFX_SPI_TRANSFER_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) &ifx_dev->rx_bus,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) if (!ifx_dev->rx_buffer) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) dev_err(dev, "DMA-RX buffer allocation failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) ret = -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) /* initialize waitq for modem reset */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) init_waitqueue_head(&ifx_dev->mdm_reset_wait);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) spi_set_drvdata(spi, ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) tasklet_setup(&ifx_dev->io_work_tasklet, ifx_spi_io);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) set_bit(IFX_SPI_STATE_PRESENT, &ifx_dev->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* create our tty port */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) ret = ifx_spi_create_port(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) if (ret != 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) dev_err(dev, "create default tty port failed");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) ifx_dev->gpio.reset = devm_gpiod_get(dev, "reset", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) if (IS_ERR(ifx_dev->gpio.reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) dev_err(dev, "could not obtain reset GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) ret = PTR_ERR(ifx_dev->gpio.reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) gpiod_set_consumer_name(ifx_dev->gpio.reset, "ifxModem reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) ifx_dev->gpio.po = devm_gpiod_get(dev, "power", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) if (IS_ERR(ifx_dev->gpio.po)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) dev_err(dev, "could not obtain power GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) ret = PTR_ERR(ifx_dev->gpio.po);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) gpiod_set_consumer_name(ifx_dev->gpio.po, "ifxModem power");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) ifx_dev->gpio.mrdy = devm_gpiod_get(dev, "mrdy", GPIOD_OUT_LOW);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) if (IS_ERR(ifx_dev->gpio.mrdy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) dev_err(dev, "could not obtain mrdy GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) ret = PTR_ERR(ifx_dev->gpio.mrdy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) gpiod_set_consumer_name(ifx_dev->gpio.mrdy, "ifxModem mrdy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) ifx_dev->gpio.srdy = devm_gpiod_get(dev, "srdy", GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) if (IS_ERR(ifx_dev->gpio.srdy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) dev_err(dev, "could not obtain srdy GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) ret = PTR_ERR(ifx_dev->gpio.srdy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) gpiod_set_consumer_name(ifx_dev->gpio.srdy, "ifxModem srdy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) ifx_dev->gpio.reset_out = devm_gpiod_get(dev, "rst_out", GPIOD_IN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) if (IS_ERR(ifx_dev->gpio.reset_out)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) dev_err(dev, "could not obtain rst_out GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) ret = PTR_ERR(ifx_dev->gpio.reset_out);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) gpiod_set_consumer_name(ifx_dev->gpio.reset_out, "ifxModem reset out");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) ifx_dev->gpio.pmu_reset = devm_gpiod_get(dev, "pmu_reset", GPIOD_ASIS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) if (IS_ERR(ifx_dev->gpio.pmu_reset)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) dev_err(dev, "could not obtain pmu_reset GPIO\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) ret = PTR_ERR(ifx_dev->gpio.pmu_reset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) gpiod_set_consumer_name(ifx_dev->gpio.pmu_reset, "ifxModem PMU reset");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) ret = request_irq(gpiod_to_irq(ifx_dev->gpio.reset_out),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) ifx_spi_reset_interrupt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) IRQF_TRIGGER_RISING|IRQF_TRIGGER_FALLING, DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) dev_err(dev, "Unable to get irq %x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) gpiod_to_irq(ifx_dev->gpio.reset_out));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) goto error_ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) ret = ifx_spi_reset(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) ret = request_irq(gpiod_to_irq(ifx_dev->gpio.srdy),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) ifx_spi_srdy_interrupt, IRQF_TRIGGER_RISING, DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) dev_err(dev, "Unable to get irq %x",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) gpiod_to_irq(ifx_dev->gpio.srdy));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) goto error_ret2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) /* set pm runtime power state and register with power system */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pm_runtime_set_active(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) pm_runtime_enable(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) /* handle case that modem is already signaling SRDY */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) /* no outgoing tty open at this point, this just satisfies the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) * modem's read and should reset communication properly
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) srdy = gpiod_get_value(ifx_dev->gpio.srdy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) if (srdy) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) mrdy_assert(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) ifx_spi_handle_srdy(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) } else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) mrdy_set_low(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) error_ret2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) free_irq(gpiod_to_irq(ifx_dev->gpio.reset_out), ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) error_ret:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) ifx_spi_free_device(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) saved_ifx_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) * ifx_spi_spi_remove - SPI device was removed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) * @spi: SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) * FIXME: We should be shutting the device down here not in
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) * the module unload path.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static int ifx_spi_spi_remove(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) /* stop activity */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) tasklet_kill(&ifx_dev->io_work_tasklet);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) pm_runtime_disable(&spi->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) /* free irq */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) free_irq(gpiod_to_irq(ifx_dev->gpio.reset_out), ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) free_irq(gpiod_to_irq(ifx_dev->gpio.srdy), ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) /* free allocations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) ifx_spi_free_device(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) saved_ifx_dev = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) * ifx_spi_spi_shutdown - called on SPI shutdown
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) * @spi: SPI device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) * No action needs to be taken here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) static void ifx_spi_spi_shutdown(struct spi_device *spi)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) ifx_modem_power_off(ifx_dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) * various suspends and resumes have nothing to do
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) * no hardware to save state for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) * ifx_spi_pm_suspend - suspend modem on system suspend
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) * @dev: device being suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) * Suspend the modem. No action needed on Intel MID platforms, may
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) * need extending for other systems.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) static int ifx_spi_pm_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) * ifx_spi_pm_resume - resume modem on system resume
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) * @dev: device being suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) * Allow the modem to resume. No action needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) * FIXME: do we need to reset anything here ?
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) static int ifx_spi_pm_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) * ifx_spi_pm_runtime_resume - suspend modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) * @dev: device being suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) * Allow the modem to resume. No action needed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) static int ifx_spi_pm_runtime_resume(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) * ifx_spi_pm_runtime_suspend - suspend modem
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) * @dev: device being suspended
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) * Allow the modem to suspend and thus suspend to continue up the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) * device tree.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) static int ifx_spi_pm_runtime_suspend(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) * ifx_spi_pm_runtime_idle - check if modem idle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) * @dev: our device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) * Check conditions and queue runtime suspend if idle.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) static int ifx_spi_pm_runtime_idle(struct device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) struct spi_device *spi = to_spi_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) struct ifx_spi_device *ifx_dev = spi_get_drvdata(spi);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) if (!ifx_dev->power_status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) pm_runtime_suspend(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) static const struct dev_pm_ops ifx_spi_pm = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) .resume = ifx_spi_pm_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) .suspend = ifx_spi_pm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) .runtime_resume = ifx_spi_pm_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) .runtime_suspend = ifx_spi_pm_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) .runtime_idle = ifx_spi_pm_runtime_idle
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) static const struct spi_device_id ifx_id_table[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) {"ifx6160", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) {"ifx6260", 0},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) MODULE_DEVICE_TABLE(spi, ifx_id_table);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) /* spi operations */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) static struct spi_driver ifx_spi_driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) .driver = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) .name = DRVNAME,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) .pm = &ifx_spi_pm,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) .probe = ifx_spi_spi_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) .shutdown = ifx_spi_spi_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) .remove = ifx_spi_spi_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) .id_table = ifx_id_table
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) * ifx_spi_exit - module exit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) * Unload the module.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1314) static void __exit ifx_spi_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1315) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1316) /* unregister */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1317) spi_unregister_driver(&ifx_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1318) tty_unregister_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1319) put_tty_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1320) unregister_reboot_notifier(&ifx_modem_reboot_notifier_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1321) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1322)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1323) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1324) * ifx_spi_init - module entry point
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1325) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1326) * Initialise the SPI and tty interfaces for the IFX SPI driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1327) * We need to initialize upper-edge spi driver after the tty
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1328) * driver because otherwise the spi probe will race
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1329) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1330)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1331) static int __init ifx_spi_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1332) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1333) int result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1334)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1335) tty_drv = alloc_tty_driver(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1336) if (!tty_drv) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1337) pr_err("%s: alloc_tty_driver failed", DRVNAME);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1338) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1339) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1340)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1341) tty_drv->driver_name = DRVNAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1342) tty_drv->name = TTYNAME;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1343) tty_drv->minor_start = IFX_SPI_TTY_ID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1344) tty_drv->type = TTY_DRIVER_TYPE_SERIAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1345) tty_drv->subtype = SERIAL_TYPE_NORMAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1346) tty_drv->flags = TTY_DRIVER_REAL_RAW | TTY_DRIVER_DYNAMIC_DEV;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1347) tty_drv->init_termios = tty_std_termios;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1349) tty_set_operations(tty_drv, &ifx_spi_serial_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1350)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1351) result = tty_register_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1352) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1353) pr_err("%s: tty_register_driver failed(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1354) DRVNAME, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1355) goto err_free_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1356) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1357)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1358) result = spi_register_driver(&ifx_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1359) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1360) pr_err("%s: spi_register_driver failed(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1361) DRVNAME, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1362) goto err_unreg_tty;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1363) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1364)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1365) result = register_reboot_notifier(&ifx_modem_reboot_notifier_block);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1366) if (result) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1367) pr_err("%s: register ifx modem reboot notifier failed(%d)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1368) DRVNAME, result);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1369) goto err_unreg_spi;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1370) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1371)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1372) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1373) err_unreg_spi:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1374) spi_unregister_driver(&ifx_spi_driver);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1375) err_unreg_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1376) tty_unregister_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1377) err_free_tty:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1378) put_tty_driver(tty_drv);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1379)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1380) return result;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1381) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1382)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1383) module_init(ifx_spi_init);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1384) module_exit(ifx_spi_exit);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1385)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1386) MODULE_AUTHOR("Intel");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1387) MODULE_DESCRIPTION("IFX6x60 spi driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1388) MODULE_LICENSE("GPL");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1389) MODULE_INFO(Version, "0.1-IFX6x60");