1// SPDX-License-Identifier: GPL-2.0-or-later
2/*
3 * netup_unidvb_spi.c
4 *
5 * Internal SPI driver for NetUP Universal Dual DVB-CI
6 *
7 * Copyright (C) 2014 NetUP Inc.
8 * Copyright (C) 2014 Sergey Kozlov <serjk@netup.ru>
9 * Copyright (C) 2014 Abylay Ospan <aospan@netup.ru>
10 */
11
12#include "netup_unidvb.h"
13#include <linux/spi/spi.h>
14#include <linux/spi/flash.h>
15#include <linux/mtd/partitions.h>
16#include <mtd/mtd-abi.h>
17
18#define NETUP_SPI_CTRL_IRQ 0x1000
19#define NETUP_SPI_CTRL_IMASK 0x2000
20#define NETUP_SPI_CTRL_START 0x8000
21#define NETUP_SPI_CTRL_LAST_CS 0x4000
22
23#define NETUP_SPI_TIMEOUT 6000
24
25enum netup_spi_state {
26 SPI_STATE_START,
27 SPI_STATE_DONE,
28};
29
30struct netup_spi_regs {
31 __u8 data[1024];
32 __le16 control_stat;
33 __le16 clock_divider;
34} __packed __aligned(1);
35
36struct netup_spi {
37 struct device *dev;
38 struct spi_controller *ctlr;
39 struct netup_spi_regs __iomem *regs;
40 u8 __iomem *mmio;
41 spinlock_t lock;
42 wait_queue_head_t waitq;
43 enum netup_spi_state state;
44};
45
46static char netup_spi_name[64] = "fpga";
47
48static struct mtd_partition netup_spi_flash_partitions = {
49 .name = netup_spi_name,
50 .size = 0x1000000, /* 16MB */
51 .offset = 0,
52 .mask_flags = MTD_CAP_ROM
53};
54
55static struct flash_platform_data spi_flash_data = {
56 .name = "netup0_m25p128",
57 .parts = &netup_spi_flash_partitions,
58 .nr_parts = 1,
59};
60
61static struct spi_board_info netup_spi_board = {
62 .modalias = "m25p128",
63 .max_speed_hz = 11000000,
64 .chip_select = 0,
65 .mode = SPI_MODE_0,
66 .platform_data = &spi_flash_data,
67};
68
69irqreturn_t netup_spi_interrupt(struct netup_spi *spi)
70{
71 u16 reg;
72 unsigned long flags;
73
74 if (!spi)
75 return IRQ_NONE;
76
77 spin_lock_irqsave(&spi->lock, flags);
78 reg = readw(addr: &spi->regs->control_stat);
79 if (!(reg & NETUP_SPI_CTRL_IRQ)) {
80 spin_unlock_irqrestore(lock: &spi->lock, flags);
81 dev_dbg(&spi->ctlr->dev,
82 "%s(): not mine interrupt\n", __func__);
83 return IRQ_NONE;
84 }
85 writew(val: reg | NETUP_SPI_CTRL_IRQ, addr: &spi->regs->control_stat);
86 reg = readw(addr: &spi->regs->control_stat);
87 writew(val: reg & ~NETUP_SPI_CTRL_IMASK, addr: &spi->regs->control_stat);
88 spi->state = SPI_STATE_DONE;
89 wake_up(&spi->waitq);
90 spin_unlock_irqrestore(lock: &spi->lock, flags);
91 dev_dbg(&spi->ctlr->dev,
92 "%s(): SPI interrupt handled\n", __func__);
93 return IRQ_HANDLED;
94}
95
96static int netup_spi_transfer(struct spi_controller *ctlr,
97 struct spi_message *msg)
98{
99 struct netup_spi *spi = spi_controller_get_devdata(ctlr);
100 struct spi_transfer *t;
101 int result = 0;
102 u32 tr_size;
103
104 /* reset CS */
105 writew(NETUP_SPI_CTRL_LAST_CS, addr: &spi->regs->control_stat);
106 writew(val: 0, addr: &spi->regs->control_stat);
107 list_for_each_entry(t, &msg->transfers, transfer_list) {
108 tr_size = t->len;
109 while (tr_size) {
110 u32 frag_offset = t->len - tr_size;
111 u32 frag_size = (tr_size > sizeof(spi->regs->data)) ?
112 sizeof(spi->regs->data) : tr_size;
113 int frag_last = 0;
114
115 if (list_is_last(list: &t->transfer_list,
116 head: &msg->transfers) &&
117 frag_offset + frag_size == t->len) {
118 frag_last = 1;
119 }
120 if (t->tx_buf) {
121 memcpy_toio(spi->regs->data,
122 t->tx_buf + frag_offset,
123 frag_size);
124 } else {
125 memset_io(spi->regs->data,
126 0, frag_size);
127 }
128 spi->state = SPI_STATE_START;
129 writew(val: (frag_size & 0x3ff) |
130 NETUP_SPI_CTRL_IMASK |
131 NETUP_SPI_CTRL_START |
132 (frag_last ? NETUP_SPI_CTRL_LAST_CS : 0),
133 addr: &spi->regs->control_stat);
134 dev_dbg(&spi->ctlr->dev,
135 "%s(): control_stat 0x%04x\n",
136 __func__, readw(&spi->regs->control_stat));
137 wait_event_timeout(spi->waitq,
138 spi->state != SPI_STATE_START,
139 msecs_to_jiffies(NETUP_SPI_TIMEOUT));
140 if (spi->state == SPI_STATE_DONE) {
141 if (t->rx_buf) {
142 memcpy_fromio(t->rx_buf + frag_offset,
143 spi->regs->data, frag_size);
144 }
145 } else {
146 if (spi->state == SPI_STATE_START) {
147 dev_dbg(&spi->ctlr->dev,
148 "%s(): transfer timeout\n",
149 __func__);
150 } else {
151 dev_dbg(&spi->ctlr->dev,
152 "%s(): invalid state %d\n",
153 __func__, spi->state);
154 }
155 result = -EIO;
156 goto done;
157 }
158 tr_size -= frag_size;
159 msg->actual_length += frag_size;
160 }
161 }
162done:
163 msg->status = result;
164 spi_finalize_current_message(ctlr);
165 return result;
166}
167
168static int netup_spi_setup(struct spi_device *spi)
169{
170 return 0;
171}
172
173int netup_spi_init(struct netup_unidvb_dev *ndev)
174{
175 struct spi_controller *ctlr;
176 struct netup_spi *nspi;
177
178 ctlr = devm_spi_alloc_master(dev: &ndev->pci_dev->dev,
179 size: sizeof(struct netup_spi));
180 if (!ctlr) {
181 dev_err(&ndev->pci_dev->dev,
182 "%s(): unable to alloc SPI master\n", __func__);
183 return -EINVAL;
184 }
185 nspi = spi_controller_get_devdata(ctlr);
186 ctlr->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST;
187 ctlr->bus_num = -1;
188 ctlr->num_chipselect = 1;
189 ctlr->transfer_one_message = netup_spi_transfer;
190 ctlr->setup = netup_spi_setup;
191 spin_lock_init(&nspi->lock);
192 init_waitqueue_head(&nspi->waitq);
193 nspi->ctlr = ctlr;
194 nspi->regs = (struct netup_spi_regs __iomem *)(ndev->bmmio0 + 0x4000);
195 writew(val: 2, addr: &nspi->regs->clock_divider);
196 writew(NETUP_UNIDVB_IRQ_SPI, addr: ndev->bmmio0 + REG_IMASK_SET);
197 ndev->spi = nspi;
198 if (spi_register_controller(ctlr)) {
199 ndev->spi = NULL;
200 dev_err(&ndev->pci_dev->dev,
201 "%s(): unable to register SPI bus\n", __func__);
202 return -EINVAL;
203 }
204 snprintf(buf: netup_spi_name,
205 size: sizeof(netup_spi_name),
206 fmt: "fpga_%02x:%02x.%01x",
207 ndev->pci_bus,
208 ndev->pci_slot,
209 ndev->pci_func);
210 if (!spi_new_device(ctlr, &netup_spi_board)) {
211 spi_unregister_controller(ctlr);
212 ndev->spi = NULL;
213 dev_err(&ndev->pci_dev->dev,
214 "%s(): unable to create SPI device\n", __func__);
215 return -EINVAL;
216 }
217 dev_dbg(&ndev->pci_dev->dev, "%s(): SPI init OK\n", __func__);
218 return 0;
219}
220
221void netup_spi_release(struct netup_unidvb_dev *ndev)
222{
223 u16 reg;
224 unsigned long flags;
225 struct netup_spi *spi = ndev->spi;
226
227 if (!spi)
228 return;
229
230 spi_unregister_controller(ctlr: spi->ctlr);
231 spin_lock_irqsave(&spi->lock, flags);
232 reg = readw(addr: &spi->regs->control_stat);
233 writew(val: reg | NETUP_SPI_CTRL_IRQ, addr: &spi->regs->control_stat);
234 reg = readw(addr: &spi->regs->control_stat);
235 writew(val: reg & ~NETUP_SPI_CTRL_IMASK, addr: &spi->regs->control_stat);
236 spin_unlock_irqrestore(lock: &spi->lock, flags);
237 ndev->spi = NULL;
238}
239
240
241

source code of linux/drivers/media/pci/netup_unidvb/netup_unidvb_spi.c