[PATCH v7 1/3] mtd: spi-nor: spansion: Add support for Read/Write Any Register
Tudor.Ambarus at microchip.com
Tudor.Ambarus at microchip.com
Mon Jan 31 23:37:37 PST 2022
On 1/31/22 13:10, Takahiro Kuwano wrote:
> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>
> On 1/31/2022 4:50 PM, Tudor.Ambarus at microchip.com wrote:
>> On 1/28/22 18:20, Pratyush Yadav wrote:
>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>
>>> On 28/01/22 09:43AM, Tudor.Ambarus at microchip.com wrote:
>>>> On 7/19/21 11:03, tkuw584924 at gmail.com wrote:
>>>>> EXTERNAL EMAIL: Do not click links or open attachments unless you know the content is safe
>>>>>
>>>>> From: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
>>>>>
>>>>> Some of Spansion/Cypress chips support Read/Write Any Register commands.
>>>>> These commands are mainly used to write volatile registers.
>>>>>
>>>>> The Read Any Register instruction (65h) is followed by register address
>>>>> and dummy cycles, then the selected register byte is returned.
>>>>>
>>>>> The Write Any Register instruction (71h) is followed by register address
>>>>> and register byte to write.
>>>>>
>>>>> Signed-off-by: Takahiro Kuwano <Takahiro.Kuwano at infineon.com>
>>>>> ---
>>>>> Changes in v7:
>>>>> - No change
>>>>>
>>>>> Changes in v6:
>>>>> - Add helper functions for controller_ops
>>>>> - Add 'reg_addr_width' parameter to spansion_read/write_any_reg()
>>>>> - Remove spi_nor_write_enable() from spansion_write_any_reg() and modified
>>>>> function header comment
>>>>>
>>>>> Changes in v5:
>>>>> - Fix 'if (ret == 1)' to 'if (ret < 0)' in spansion_read_any_reg()
>>>>>
>>>>> Changes in v4:
>>>>> - Fix dummy cycle calculation in spansion_read_any_reg()
>>>>> - Modify comment for spansion_write_any_reg()
>>>>>
>>>>> Changes in v3:
>>>>> - Cleanup implementation
>>>>>
>>>>> drivers/mtd/spi-nor/spansion.c | 142 +++++++++++++++++++++++++++++++++
>>>>> 1 file changed, 142 insertions(+)
>>>>>
>>>>> +/**
>>>>> + * spansion_read_any_reg() - Read Any Register.
>>>>> + * @nor: pointer to a 'struct spi_nor'
>>>>> + * @reg_addr: register address
>>>>> + * @reg_addr_width: number of address bytes
>>>>> + * @reg_dummy: number of dummy cycles for register read
>>>>> + * @reg_val: pointer to a buffer where the register value is copied
>>>>> + *
>>>>> + * Return: 0 on success, -errno otherwise.
>>>>> + */
>>>>> +static int spansion_read_any_reg(struct spi_nor *nor, u32 reg_addr,
>>>>> + u8 reg_addr_width, u8 reg_dummy, u8 *reg_val)
>>>>
>>>> how about making this a generic core method? I'm sure there are other SPI NOR
>>>> vendors that use registers indexed by address. How about introducing:
>>>>
>>>> struct spi_nor_reg {
>>>> u32 addr;
>>>> u8 addr_width;
>>>> u8 dummy;
>>>> u8 opcode;
>>>> u8 val;
>>>> };
>>>>
>>>> and passing a pointer to this struct as argument.
>>>
>>> Wouldn't it be simpler if they fill it in a struct spi_mem_op, and then
>>> just pass that in as a "template"?
>>>
>> sure, sounds fine. I would like a generic method with less function parameters,
>> if possible. Let's see what Takahiro will propose.
>
> So, I would propose...
> In core, spi_nor_spimem_{read,write}_reg(struct spi_nor *, struct spi_mem_op *)
> that calls spi_nor_spimem_setup() and spi_mem_exec_op().
> In vendor specific, spi_mem_op is filled and passed to the core method.
>
how about the following?
static ssize_t spi_nor_spimem_read_reg(struct spi_nor *nor, struct spi_mem_op *op)
{
bool usebouncebuf;
ssize_t nbytes;
int error;
spi_nor_spimem_setup_op(nor, &op, nor->read_proto);
/* convert the dummy cycles to the number of bytes */
op.dummy.nbytes = (nor->read_dummy * op.dummy.buswidth) / 8;
if (spi_nor_protocol_is_dtr(nor->read_proto))
op.dummy.nbytes *= 2;
usebouncebuf = spi_nor_spimem_bounce(nor, &op);
ret = spi_nor_spimem_exec_op(nor, &op);
if (ret)
return ret;
nbytes = op.data.nbytes;
if (usebouncebuf && nbytes > 0)
memcpy(buf, op.data.buf.in, nbytes);
return nbytes;
}
ssize_t spi_nor_read_reg(struct spi_nor *nor, struct spi_mem_op *op)
{
if (nor->spimem)
return spi_nor_spimem_read_reg(nor, from, len, buf);
return -EOPNOTSUPP;
}
More information about the linux-mtd
mailing list