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 | |
25 | enum netup_spi_state { |
26 | SPI_STATE_START, |
27 | SPI_STATE_DONE, |
28 | }; |
29 | |
30 | struct netup_spi_regs { |
31 | __u8 data[1024]; |
32 | __le16 control_stat; |
33 | __le16 clock_divider; |
34 | } __packed __aligned(1); |
35 | |
36 | struct 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 | |
46 | static char netup_spi_name[64] = "fpga" ; |
47 | |
48 | static 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 | |
55 | static struct flash_platform_data spi_flash_data = { |
56 | .name = "netup0_m25p128" , |
57 | .parts = &netup_spi_flash_partitions, |
58 | .nr_parts = 1, |
59 | }; |
60 | |
61 | static 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 | |
69 | irqreturn_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 | |
96 | static 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 | } |
162 | done: |
163 | msg->status = result; |
164 | spi_finalize_current_message(ctlr); |
165 | return result; |
166 | } |
167 | |
168 | static int netup_spi_setup(struct spi_device *spi) |
169 | { |
170 | return 0; |
171 | } |
172 | |
173 | int 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 | |
221 | void 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 | |