blob: 84569845b74c31582c8353aa5babd2381f9a4783 [file] [log] [blame]
Pengpeng Chen8f04b522020-07-30 12:52:45 -07001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Driver for Cortina SPI-FLASH Controller
4 *
5 * Copyright (C) 2020 Cortina Access Inc. All Rights Reserved.
6 *
7 * Author: PengPeng Chen <pengpeng.chen@cortina-access.com>
8 */
9
10#include <common.h>
11#include <malloc.h>
12#include <clk.h>
13#include <dm.h>
14#include <errno.h>
15#include <fdtdec.h>
16#include <linux/compat.h>
17#include <linux/io.h>
18#include <linux/iopoll.h>
19#include <linux/ioport.h>
20#include <linux/sizes.h>
21#include <spi.h>
22#include <spi-mem.h>
23#include <reset.h>
24
25DECLARE_GLOBAL_DATA_PTR;
26
27struct ca_sflash_regs {
28 u32 idr; /* 0x00:Flash word ID Register */
29 u32 tc; /* 0x04:Flash Timeout Counter Register */
30 u32 sr; /* 0x08:Flash Status Register */
31 u32 tr; /* 0x0C:Flash Type Register */
32 u32 asr; /* 0x10:Flash ACCESS START/BUSY Register */
33 u32 isr; /* 0x14:Flash Interrupt Status Register */
34 u32 imr; /* 0x18:Flash Interrupt Mask Register */
35 u32 fcr; /* 0x1C:NAND Flash FIFO Control Register */
36 u32 ffsr; /* 0x20:Flash FIFO Status Register */
37 u32 ffar; /* 0x24:Flash FIFO ADDRESS Register */
38 u32 ffmar; /* 0x28:Flash FIFO MATCHING ADDRESS Register */
39 u32 ffdr; /* 0x2C:Flash FIFO Data Register */
40 u32 ar; /* 0x30:Serial Flash Access Register */
41 u32 ear; /* 0x34:Serial Flash Extend Access Register */
42 u32 adr; /* 0x38:Serial Flash ADdress Register */
43 u32 dr; /* 0x3C:Serial Flash Data Register */
44 u32 tmr; /* 0x40:Serial Flash Timing Register */
45};
46
47/*
48 * FLASH_TYPE
49 */
50#define CA_FLASH_TR_PIN BIT(15)
51#define CA_FLASH_TR_TYPE_MSK GENMASK(14, 12)
52#define CA_FLASH_TR_TYPE(tp) (((tp) << 12) & CA_FLASH_TR_TYPE_MSK)
53#define CA_FLASH_TR_WIDTH BIT(11)
54#define CA_FLASH_TR_SIZE_MSK GENMASK(10, 9)
55#define CA_FLASH_TR_SIZE(sz) (((sz) << 9) & CA_FLASH_TR_SIZE_MSK)
56
57/*
58 * FLASH_FLASH_ACCESS_START
59 */
60#define CA_FLASH_ASR_IND_START_EN BIT(1)
61#define CA_FLASH_ASR_DMA_START_EN BIT(3)
62#define CA_FLASH_ASR_WR_ACCESS_EN BIT(9)
63
64/*
65 * FLASH_FLASH_INTERRUPT
66 */
67#define CA_FLASH_ISR_REG_IRQ BIT(1)
68#define CA_FLASH_ISR_FIFO_IRQ BIT(2)
69
70/*
71 * FLASH_SF_ACCESS
72 */
73#define CA_SF_AR_OP_MSK GENMASK(7, 0)
74#define CA_SF_AR_OP(op) ((op) << 0 & CA_SF_AR_OP_MSK)
75#define CA_SF_AR_ACCODE_MSK GENMASK(11, 8)
76#define CA_SF_AR_ACCODE(ac) (((ac) << 8) & CA_SF_AR_ACCODE_MSK)
77#define CA_SF_AR_FORCE_TERM BIT(12)
78#define CA_SF_AR_FORCE_BURST BIT(13)
79#define CA_SF_AR_AUTO_MODE_EN BIT(15)
80#define CA_SF_AR_CHIP_EN_ALT BIT(16)
81#define CA_SF_AR_HI_SPEED_RD BIT(17)
82#define CA_SF_AR_MIO_INF_DC BIT(24)
83#define CA_SF_AR_MIO_INF_AC BIT(25)
84#define CA_SF_AR_MIO_INF_CC BIT(26)
85#define CA_SF_AR_DDR_MSK GENMASK(29, 28)
86#define CA_SF_AR_DDR(ddr) (((ddr) << 28) & CA_SF_AR_DDR_MSK)
87#define CA_SF_AR_MIO_INF_MSK GENMASK(31, 30)
88#define CA_SF_AR_MIO_INF(io) (((io) << 30) & CA_SF_AR_MIO_INF_MSK)
89
90/*
91 * FLASH_SF_EXT_ACCESS
92 */
93#define CA_SF_EAR_OP_MSK GENMASK(7, 0)
94#define CA_SF_EAR_OP(op) (((op) << 0) & CA_SF_EAR_OP_MSK)
95#define CA_SF_EAR_DATA_CNT_MSK GENMASK(20, 8)
96#define CA_SF_EAR_DATA_CNT(cnt) (((cnt) << 8) & CA_SF_EAR_DATA_CNT_MSK)
97#define CA_SF_EAR_DATA_CNT_MAX (4096)
98#define CA_SF_EAR_ADDR_CNT_MSK GENMASK(23, 21)
99#define CA_SF_EAR_ADDR_CNT(cnt) (((cnt) << 21) & CA_SF_EAR_ADDR_CNT_MSK)
100#define CA_SF_EAR_ADDR_CNT_MAX (5)
101#define CA_SF_EAR_DUMY_CNT_MSK GENMASK(29, 24)
102#define CA_SF_EAR_DUMY_CNT(cnt) (((cnt) << 24) & CA_SF_EAR_DUMY_CNT_MSK)
103#define CA_SF_EAR_DUMY_CNT_MAX (32)
104#define CA_SF_EAR_DRD_CMD_EN BIT(31)
105
106/*
107 * FLASH_SF_ADDRESS
108 */
109#define CA_SF_ADR_REG_MSK GENMASK(31, 0)
110#define CA_SF_ADR_REG(addr) (((addr) << 0) & CA_SF_ADR_REG_MSK)
111
112/*
113 * FLASH_SF_DATA
114 */
115#define CA_SF_DR_REG_MSK GENMASK(31, 0)
116#define CA_SF_DR_REG(addr) (((addr) << 0) & CA_SF_DR_REG_MSK)
117
118/*
119 * FLASH_SF_TIMING
120 */
121#define CA_SF_TMR_IDLE_MSK GENMASK(7, 0)
122#define CA_SF_TMR_IDLE(idle) (((idle) << 0) & CA_SF_TMR_IDLE_MSK)
123#define CA_SF_TMR_HOLD_MSK GENMASK(15, 8)
124#define CA_SF_TMR_HOLD(hold) (((hold) << 8) & CA_SF_TMR_HOLD_MSK)
125#define CA_SF_TMR_SETUP_MSK GENMASK(23, 16)
126#define CA_SF_TMR_SETUP(setup) (((setup) << 16) & CA_SF_TMR_SETUP_MSK)
127#define CA_SF_TMR_CLK_MSK GENMASK(26, 24)
128#define CA_SF_TMR_CLK(clk) (((clk) << 24) & CA_SF_TMR_CLK_MSK)
129
130#define CA_SFLASH_IND_WRITE 0
131#define CA_SFLASH_IND_READ 1
132#define CA_SFLASH_MEM_MAP 3
133#define CA_SFLASH_FIFO_TIMEOUT_US 30000
134#define CA_SFLASH_BUSY_TIMEOUT_US 40000
135
136#define CA_SF_AC_OP 0x00
137#define CA_SF_AC_OP_1_DATA 0x01
138#define CA_SF_AC_OP_2_DATA 0x02
139#define CA_SF_AC_OP_3_DATA 0x03
140#define CA_SF_AC_OP_4_DATA 0x04
141#define CA_SF_AC_OP_3_ADDR 0x05
142#define CA_SF_AC_OP_4_ADDR (CA_SF_AC_OP_3_ADDR)
143#define CA_SF_AC_OP_3_ADDR_1_DATA 0x06
144#define CA_SF_AC_OP_4_ADDR_1_DATA (CA_SF_AC_OP_3_ADDR_1_DATA << 2)
145#define CA_SF_AC_OP_3_ADDR_2_DATA 0x07
146#define CA_SF_AC_OP_4_ADDR_2_DATA (CA_SF_AC_OP_3_ADDR_2_DATA << 2)
147#define CA_SF_AC_OP_3_ADDR_3_DATA 0x08
148#define CA_SF_AC_OP_4_ADDR_3_DATA (CA_SF_AC_OP_3_ADDR_3_DATA << 2)
149#define CA_SF_AC_OP_3_ADDR_4_DATA 0x09
150#define CA_SF_AC_OP_4_ADDR_4_DATA (CA_SF_AC_OP_3_ADDR_4_DATA << 2)
151#define CA_SF_AC_OP_3_ADDR_X_1_DATA 0x0A
152#define CA_SF_AC_OP_4_ADDR_X_1_DATA (CA_SF_AC_OP_3_ADDR_X_1_DATA << 2)
153#define CA_SF_AC_OP_3_ADDR_X_2_DATA 0x0B
154#define CA_SF_AC_OP_4_ADDR_X_2_DATA (CA_SF_AC_OP_3_ADDR_X_2_DATA << 2)
155#define CA_SF_AC_OP_3_ADDR_X_3_DATA 0x0C
156#define CA_SF_AC_OP_4_ADDR_X_3_DATA (CA_SF_AC_OP_3_ADDR_X_3_DATA << 2)
157#define CA_SF_AC_OP_3_ADDR_X_4_DATA 0x0D
158#define CA_SF_AC_OP_4_ADDR_X_4_DATA (CA_SF_AC_OP_3_ADDR_X_4_DATA << 2)
159#define CA_SF_AC_OP_3_ADDR_4X_1_DATA 0x0E
160#define CA_SF_AC_OP_4_ADDR_4X_1_DATA (CA_SF_AC_OP_3_ADDR_4X_1_DATA << 2)
161#define CA_SF_AC_OP_EXTEND 0x0F
162
163#define CA_SF_ACCESS_MIO_SINGLE 0
164#define CA_SF_ACCESS_MIO_DUAL 1
165#define CA_SF_ACCESS_MIO_QUARD 2
166
167enum access_type {
168 RD_ACCESS,
169 WR_ACCESS,
170};
171
172struct ca_sflash_priv {
173 struct ca_sflash_regs *regs;
174 u8 rx_width;
175 u8 tx_width;
176};
177
178/*
179 * This function doesn't do anything except help with debugging
180 */
181static int ca_sflash_claim_bus(struct udevice *dev)
182{
183 debug("%s:\n", __func__);
184 return 0;
185}
186
187static int ca_sflash_release_bus(struct udevice *dev)
188{
189 debug("%s:\n", __func__);
190 return 0;
191}
192
193static int ca_sflash_set_speed(struct udevice *dev, uint speed)
194{
195 debug("%s:\n", __func__);
196 return 0;
197}
198
199static int ca_sflash_set_mode(struct udevice *dev, uint mode)
200{
201 struct ca_sflash_priv *priv = dev_get_priv(dev);
202
203 if (mode & SPI_RX_QUAD)
204 priv->rx_width = 4;
205 else if (mode & SPI_RX_DUAL)
206 priv->rx_width = 2;
207 else
208 priv->rx_width = 1;
209
210 if (mode & SPI_TX_QUAD)
211 priv->tx_width = 4;
212 else if (mode & SPI_TX_DUAL)
213 priv->tx_width = 2;
214 else
215 priv->tx_width = 1;
216
217 debug("%s: mode=%d, rx_width=%d, tx_width=%d\n",
218 __func__, mode, priv->rx_width, priv->tx_width);
219
220 return 0;
221}
222
223static int _ca_sflash_wait_for_not_busy(struct ca_sflash_priv *priv)
224{
225 u32 asr;
226
227 if (readl_poll_timeout(&priv->regs->asr, asr,
228 !(asr & CA_FLASH_ASR_IND_START_EN),
229 CA_SFLASH_BUSY_TIMEOUT_US)) {
230 pr_err("busy timeout (stat:%#x)\n", asr);
231 return -1;
232 }
233
234 return 0;
235}
236
237static int _ca_sflash_wait_cmd(struct ca_sflash_priv *priv,
238 enum access_type type)
239{
240 if (type == WR_ACCESS) {
241 /* Enable write access and start the sflash indirect access */
242 clrsetbits_le32(&priv->regs->asr, GENMASK(31, 0),
243 CA_FLASH_ASR_WR_ACCESS_EN
244 | CA_FLASH_ASR_IND_START_EN);
245 } else if (type == RD_ACCESS) {
246 /* Start the sflash indirect access */
247 clrsetbits_le32(&priv->regs->asr, GENMASK(31, 0),
248 CA_FLASH_ASR_IND_START_EN);
249 } else {
250 printf("%s: !error access type.\n", __func__);
251 return -1;
252 }
253
254 /* Wait til the action(rd/wr) completed */
255 return _ca_sflash_wait_for_not_busy(priv);
256}
257
258static int _ca_sflash_read(struct ca_sflash_priv *priv,
259 u8 *buf, unsigned int data_len)
260{
261 u32 reg_data;
262 int len;
263
264 len = data_len;
265 while (len >= 4) {
266 if (_ca_sflash_wait_cmd(priv, RD_ACCESS))
267 return -1;
268 reg_data = readl(&priv->regs->dr);
269 *buf++ = reg_data & 0xFF;
270 *buf++ = (reg_data >> 8) & 0xFF;
271 *buf++ = (reg_data >> 16) & 0xFF;
272 *buf++ = (reg_data >> 24) & 0xFF;
273 len -= 4;
274 debug("%s: reg_data=%#08x\n",
275 __func__, reg_data);
276 }
277
278 if (len > 0) {
279 if (_ca_sflash_wait_cmd(priv, RD_ACCESS))
280 return -1;
281 reg_data = readl(&priv->regs->dr);
282 debug("%s: reg_data=%#08x\n",
283 __func__, reg_data);
284 }
285
286 switch (len) {
287 case 3:
288 *buf++ = reg_data & 0xFF;
289 *buf++ = (reg_data >> 8) & 0xFF;
290 *buf++ = (reg_data >> 16) & 0xFF;
291 break;
292 case 2:
293 *buf++ = reg_data & 0xFF;
294 *buf++ = (reg_data >> 8) & 0xFF;
295 break;
296 case 1:
297 *buf++ = reg_data & 0xFF;
298 break;
299 case 0:
300 break;
301 default:
302 printf("%s: error data_length %d!\n", __func__, len);
303 }
304
305 return 0;
306}
307
308static int _ca_sflash_mio_set(struct ca_sflash_priv *priv,
309 u8 width)
310{
311 if (width == 4) {
312 setbits_le32(&priv->regs->ar,
313 CA_SF_AR_MIO_INF_DC
314 | CA_SF_AR_MIO_INF(CA_SF_ACCESS_MIO_QUARD)
315 | CA_SF_AR_FORCE_BURST);
316 } else if (width == 2) {
317 setbits_le32(&priv->regs->ar,
318 CA_SF_AR_MIO_INF_DC
319 | CA_SF_AR_MIO_INF(CA_SF_ACCESS_MIO_DUAL)
320 | CA_SF_AR_FORCE_BURST);
321 } else if (width == 1) {
322 setbits_le32(&priv->regs->ar,
323 CA_SF_AR_MIO_INF(CA_SF_ACCESS_MIO_SINGLE)
324 | CA_SF_AR_FORCE_BURST);
325 } else {
326 printf("%s: error rx/tx width %d!\n", __func__, width);
327 return -1;
328 }
329
330 return 0;
331}
332
333static int _ca_sflash_write(struct ca_sflash_priv *priv,
334 u8 *buf, unsigned int data_len)
335{
336 u32 reg_data;
337 int len;
338
339 len = data_len;
340 while (len > 0) {
341 reg_data = buf[0]
342 | (buf[1] << 8)
343 | (buf[2] << 16)
344 | (buf[3] << 24);
345
346 debug("%s: reg_data=%#08x\n",
347 __func__, reg_data);
348 /* Fill data */
349 clrsetbits_le32(&priv->regs->dr, GENMASK(31, 0), reg_data);
350
351 if (_ca_sflash_wait_cmd(priv, WR_ACCESS))
352 return -1;
353
354 len -= 4;
355 buf += 4;
356 }
357
358 return 0;
359}
360
361static int _ca_sflash_access_data(struct ca_sflash_priv *priv,
362 struct spi_mem_op *op)
363{
364 int total_cnt;
365 unsigned int len;
366 unsigned int data_cnt = op->data.nbytes;
367 u64 addr_offset = op->addr.val;
368 u8 addr_cnt = op->addr.nbytes;
369 u8 *data_buf = NULL;
370 u8 *buf = NULL;
371
372 if (op->data.dir == SPI_MEM_DATA_IN)
373 data_buf = (u8 *)op->data.buf.in;
374 else
375 data_buf = (u8 *)op->data.buf.out;
376
377 if (data_cnt > CA_SF_EAR_DATA_CNT_MAX)
378 buf = malloc(CA_SF_EAR_DATA_CNT_MAX);
379 else
380 buf = malloc(data_cnt);
381
382 total_cnt = data_cnt;
383 while (total_cnt > 0) {
384 /* Fill address */
385 if (addr_cnt > 0)
386 clrsetbits_le32(&priv->regs->adr,
387 GENMASK(31, 0), (u32)addr_offset);
388
389 if (total_cnt > CA_SF_EAR_DATA_CNT_MAX) {
390 len = CA_SF_EAR_DATA_CNT_MAX;
391 addr_offset += CA_SF_EAR_DATA_CNT_MAX;
392 /* Clear start bit before next bulk read */
393 clrbits_le32(&priv->regs->asr, GENMASK(31, 0));
394 } else {
395 len = total_cnt;
396 }
397
398 memset(buf, 0, len);
399 if (op->data.dir == SPI_MEM_DATA_IN) {
400 if (_ca_sflash_read(priv, buf, len))
401 break;
402 memcpy(data_buf, buf, len);
403 } else {
404 memcpy(buf, data_buf, len);
405 if (_ca_sflash_write(priv, buf, len))
406 break;
407 }
408
409 total_cnt -= len;
410 data_buf += len;
411 }
412 if (buf)
413 free(buf);
414
415 return total_cnt > 0 ? -1 : 0;
416}
417
418static int _ca_sflash_issue_cmd(struct ca_sflash_priv *priv,
419 struct spi_mem_op *op, u8 opcode)
420{
421 u8 dummy_cnt = op->dummy.nbytes;
422 u8 addr_cnt = op->addr.nbytes;
423 u8 mio_width;
424 unsigned int data_cnt = op->data.nbytes;
425 u64 addr_offset = op->addr.val;
426
427 /* Set the access register */
428 clrsetbits_le32(&priv->regs->ar,
429 GENMASK(31, 0), CA_SF_AR_ACCODE(opcode));
430
431 if (opcode == CA_SF_AC_OP_EXTEND) { /* read_data, write_data */
432 if (data_cnt > 6) {
433 if (op->data.dir == SPI_MEM_DATA_IN)
434 mio_width = priv->rx_width;
435 else
436 mio_width = priv->tx_width;
437 if (_ca_sflash_mio_set(priv, mio_width))
438 return -1;
439 }
440 debug("%s: FLASH ACCESS reg=%#08x\n",
441 __func__, readl(&priv->regs->ar));
442
443 /* Use command in extend_access register */
444 clrsetbits_le32(&priv->regs->ear,
445 GENMASK(31, 0), CA_SF_EAR_OP(op->cmd.opcode)
446 | CA_SF_EAR_DUMY_CNT(dummy_cnt * 8 - 1)
447 | CA_SF_EAR_ADDR_CNT(addr_cnt - 1)
448 | CA_SF_EAR_DATA_CNT(4 - 1)
449 | CA_SF_EAR_DRD_CMD_EN);
450 debug("%s: FLASH EXT ACCESS reg=%#08x\n",
451 __func__, readl(&priv->regs->ear));
452
453 if (_ca_sflash_access_data(priv, op))
454 return -1;
455 } else { /* reset_op, wr_enable, wr_disable */
456 setbits_le32(&priv->regs->ar,
457 CA_SF_AR_OP(op->cmd.opcode));
458 debug("%s: FLASH ACCESS reg=%#08x\n",
459 __func__, readl(&priv->regs->ar));
460
461 if (opcode == CA_SF_AC_OP_4_ADDR) { /* erase_op */
462 /* Configure address length */
463 if (addr_cnt > 3) /* 4 Bytes address */
464 setbits_le32(&priv->regs->tr,
465 CA_FLASH_TR_SIZE(2));
466 else /* 3 Bytes address */
467 clrbits_le32(&priv->regs->tr,
468 CA_FLASH_TR_SIZE_MSK);
469
470 /* Fill address */
471 if (addr_cnt > 0)
472 clrsetbits_le32(&priv->regs->adr,
473 GENMASK(31, 0),
474 (u32)addr_offset);
475 }
476
477 if (_ca_sflash_wait_cmd(priv, RD_ACCESS))
478 return -1;
479 }
480 /* elapse 10us before issuing any other command */
481 udelay(10);
482
483 return 0;
484}
485
486static int ca_sflash_exec_op(struct spi_slave *slave,
487 const struct spi_mem_op *op)
488{
489 struct ca_sflash_priv *priv = dev_get_priv(slave->dev->parent);
490 u8 opcode;
491
492 debug("%s: cmd:%#02x addr.val:%#llx addr.len:%#x data.len:%#x data.dir:%#x\n",
493 __func__, op->cmd.opcode, op->addr.val,
494 op->addr.nbytes, op->data.nbytes, op->data.dir);
495
496 if (op->data.nbytes == 0 && op->addr.nbytes == 0) {
497 opcode = CA_SF_AC_OP;
498 } else if (op->data.nbytes == 0 && op->addr.nbytes > 0) {
499 opcode = CA_SF_AC_OP_4_ADDR;
500 } else if (op->data.nbytes > 0) {
501 opcode = CA_SF_AC_OP_EXTEND;
502 } else {
503 printf("%s: can't support cmd.opcode:(%#02x) type currently!\n",
504 __func__, op->cmd.opcode);
505 return -1;
506 }
507
508 return _ca_sflash_issue_cmd(priv, (struct spi_mem_op *)op, opcode);
509}
510
511static void ca_sflash_init(struct ca_sflash_priv *priv)
512{
513 /* Set FLASH_TYPE as serial flash, value: 0x0400*/
514 clrsetbits_le32(&priv->regs->tr,
515 GENMASK(31, 0), CA_FLASH_TR_SIZE(2));
516 debug("%s: FLASH_TYPE reg=%#x\n",
517 __func__, readl(&priv->regs->tr));
518
519 /* Minimize flash timing, value: 0x07010101 */
520 clrsetbits_le32(&priv->regs->tmr,
521 GENMASK(31, 0),
522 CA_SF_TMR_CLK(0x07)
523 | CA_SF_TMR_SETUP(0x01)
524 | CA_SF_TMR_HOLD(0x01)
525 | CA_SF_TMR_IDLE(0x01));
526 debug("%s: FLASH_TIMING reg=%#x\n",
527 __func__, readl(&priv->regs->tmr));
528}
529
530static int ca_sflash_probe(struct udevice *dev)
531{
532 struct ca_sflash_priv *priv = dev_get_priv(dev);
533 struct resource res;
534 int ret;
535
536 /* Map the registers */
537 ret = dev_read_resource_byname(dev, "sflash-regs", &res);
538 if (ret) {
539 dev_err(dev, "can't get regs base addresses(ret = %d)!\n", ret);
540 return ret;
541 }
542 priv->regs = devm_ioremap(dev, res.start, resource_size(&res));
543 if (IS_ERR(priv->regs))
544 return PTR_ERR(priv->regs);
545
546 ca_sflash_init(priv);
547
548 printf("SFLASH: Controller probed ready\n");
549 return 0;
550}
551
552static const struct spi_controller_mem_ops ca_sflash_mem_ops = {
553 .exec_op = ca_sflash_exec_op,
554};
555
556static const struct dm_spi_ops ca_sflash_ops = {
557 .claim_bus = ca_sflash_claim_bus,
558 .release_bus = ca_sflash_release_bus,
559 .set_speed = ca_sflash_set_speed,
560 .set_mode = ca_sflash_set_mode,
561 .mem_ops = &ca_sflash_mem_ops,
562};
563
564static const struct udevice_id ca_sflash_ids[] = {
565 {.compatible = "cortina,ca-sflash"},
566 {}
567};
568
569U_BOOT_DRIVER(ca_sflash) = {
570 .name = "ca_sflash",
571 .id = UCLASS_SPI,
572 .of_match = ca_sflash_ids,
573 .ops = &ca_sflash_ops,
Dario Binacchif686e4d2021-01-15 09:10:26 +0100574 .priv_auto = sizeof(struct ca_sflash_priv),
Pengpeng Chen8f04b522020-07-30 12:52:45 -0700575 .probe = ca_sflash_probe,
576};