1 #include <linux/module.h>
2 #include <linux/delay.h>
3 #include <linux/spi/spi.h>
4 #include <linux/mtd/spi-nor.h>
5 #include <linux/mtd/mtd.h>
6 #include <linux/mtd/cfi.h>
7 #include <linux/mtd/partitions.h>
9 static const char * const probes
[] = { "ofpart", "bcm47xxpart", NULL
};
12 struct spi_device
*spi
;
17 /**************************************************
19 **************************************************/
21 static int bcm53xxspiflash_read_reg(struct spi_nor
*nor
, u8 opcode
, u8
*buf
,
24 struct bcm53xxsf
*b53sf
= nor
->priv
;
26 return spi_write_then_read(b53sf
->spi
, &opcode
, 1, buf
, len
);
29 static int bcm53xxspiflash_write_reg(struct spi_nor
*nor
, u8 opcode
, u8
*buf
,
30 int len
, int write_enable
)
32 struct bcm53xxsf
*b53sf
= nor
->priv
;
33 u8
*cmd
= kzalloc(len
+ 1, GFP_KERNEL
);
40 memcpy(&cmd
[1], buf
, len
);
41 err
= spi_write(b53sf
->spi
, cmd
, len
+ 1);
48 static int bcm53xxspiflash_read(struct spi_nor
*nor
, loff_t from
, size_t len
,
49 size_t *retlen
, u_char
*buf
)
51 struct bcm53xxsf
*b53sf
= nor
->priv
;
53 struct spi_transfer t
[2] = { { 0 }, { 0 } };
60 cmd
[cmd_len
++] = SPINOR_OP_READ
;
61 if (b53sf
->mtd
.size
> 0x1000000)
62 cmd
[cmd_len
++] = (from
& 0xFF000000) >> 24;
63 cmd
[cmd_len
++] = (from
& 0x00FF0000) >> 16;
64 cmd
[cmd_len
++] = (from
& 0x0000FF00) >> 8;
65 cmd
[cmd_len
++] = (from
& 0x000000FF) >> 0;
69 spi_message_add_tail(&t
[0], &m
);
73 spi_message_add_tail(&t
[1], &m
);
75 err
= spi_sync(b53sf
->spi
, &m
);
79 if (retlen
&& m
.actual_length
> cmd_len
)
80 *retlen
= m
.actual_length
- cmd_len
;
85 static void bcm53xxspiflash_write(struct spi_nor
*nor
, loff_t to
, size_t len
,
86 size_t *retlen
, const u_char
*buf
)
88 struct bcm53xxsf
*b53sf
= nor
->priv
;
90 struct spi_transfer t
= { 0 };
91 u8
*cmd
= kzalloc(len
+ 5, GFP_KERNEL
);
100 cmd
[cmd_len
++] = nor
->program_opcode
;
101 if (b53sf
->mtd
.size
> 0x1000000)
102 cmd
[cmd_len
++] = (to
& 0xFF000000) >> 24;
103 cmd
[cmd_len
++] = (to
& 0x00FF0000) >> 16;
104 cmd
[cmd_len
++] = (to
& 0x0000FF00) >> 8;
105 cmd
[cmd_len
++] = (to
& 0x000000FF) >> 0;
106 memcpy(&cmd
[cmd_len
], buf
, len
);
109 t
.len
= cmd_len
+ len
;
110 spi_message_add_tail(&t
, &m
);
112 err
= spi_sync(b53sf
->spi
, &m
);
116 if (retlen
&& m
.actual_length
> cmd_len
)
117 *retlen
+= m
.actual_length
- cmd_len
;
123 static int bcm53xxspiflash_erase(struct spi_nor
*nor
, loff_t offs
)
125 struct bcm53xxsf
*b53sf
= nor
->priv
;
126 unsigned char cmd
[5];
130 cmd
[i
++] = nor
->erase_opcode
;
131 if (b53sf
->mtd
.size
> 0x1000000)
132 cmd
[i
++] = (offs
& 0xFF000000) >> 24;
133 cmd
[i
++] = ((offs
& 0x00FF0000) >> 16);
134 cmd
[i
++] = ((offs
& 0x0000FF00) >> 8);
135 cmd
[i
++] = ((offs
& 0x000000FF) >> 0);
137 return spi_write(b53sf
->spi
, cmd
, i
);
140 static const char *bcm53xxspiflash_chip_name(struct spi_nor
*nor
)
142 struct bcm53xxsf
*b53sf
= nor
->priv
;
143 struct device
*dev
= &b53sf
->spi
->dev
;
144 unsigned char cmd
[4];
145 unsigned char resp
[2];
148 /* SST and Winbond/NexFlash specific command */
149 cmd
[0] = 0x90; /* Read Manufacturer / Device ID */
153 err
= spi_write_then_read(b53sf
->spi
, cmd
, 4, resp
, 2);
155 dev_err(dev
, "error reading SPI flash id\n");
156 return ERR_PTR(-EBUSY
);
159 case 0xef: /* Winbond/NexFlash */
164 dev_err(dev
, "Unknown Winbond/NexFlash flash: %02X %02X\n",
169 /* TODO: Try more ID commands */
174 /**************************************************
176 **************************************************/
178 static int bcm53xxspiflash_probe(struct spi_device
*spi
)
180 struct mtd_part_parser_data parser_data
= {};
181 struct bcm53xxsf
*b53sf
;
185 b53sf
= devm_kzalloc(&spi
->dev
, sizeof(*b53sf
), GFP_KERNEL
);
188 spi_set_drvdata(spi
, b53sf
);
192 b53sf
->mtd
.priv
= &b53sf
->nor
;
194 nor
->mtd
= &b53sf
->mtd
;
195 nor
->dev
= &spi
->dev
;
196 nor
->read_reg
= bcm53xxspiflash_read_reg
;
197 nor
->write_reg
= bcm53xxspiflash_write_reg
;
198 nor
->read
= bcm53xxspiflash_read
;
199 nor
->write
= bcm53xxspiflash_write
;
200 nor
->erase
= bcm53xxspiflash_erase
;
203 err
= spi_nor_scan(&b53sf
->nor
, bcm53xxspiflash_chip_name(nor
),
208 parser_data
.of_node
= spi
->master
->dev
.parent
->of_node
;
209 err
= mtd_device_parse_register(&b53sf
->mtd
, probes
, &parser_data
,
217 static int bcm53xxspiflash_remove(struct spi_device
*spi
)
222 static struct spi_driver bcm53xxspiflash_driver
= {
224 .name
= "bcm53xxspiflash",
225 .owner
= THIS_MODULE
,
227 .probe
= bcm53xxspiflash_probe
,
228 .remove
= bcm53xxspiflash_remove
,
231 module_spi_driver(bcm53xxspiflash_driver
);