[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <ad1a8507-49df-49c6-a285-8adb407ad7a1@baylibre.com>
Date: Thu, 5 Sep 2024 14:11:49 +0200
From: Angelo Dureghello <adureghello@...libre.com>
To: Nuno Sá <noname.nuno@...il.com>,
Jonathan Cameron <jic23@...nel.org>
Cc: Lars-Peter Clausen <lars@...afoo.de>,
Michael Hennerich <Michael.Hennerich@...log.com>,
Nuno Sá <nuno.sa@...log.com>, Rob Herring
<robh@...nel.org>, Krzysztof Kozlowski <krzk+dt@...nel.org>,
Conor Dooley <conor+dt@...nel.org>,
Olivier Moysan <olivier.moysan@...s.st.com>, linux-iio@...r.kernel.org,
devicetree@...r.kernel.org, linux-kernel@...r.kernel.org,
dlechner@...libre.com
Subject: Re: [PATCH RFC 3/8] iio: backend adi-axi-dac: backend features
Hi,
sorry forgot to reply about the regmap,
On 05/09/24 12:49 PM, Nuno Sá wrote:
> On Tue, 2024-09-03 at 20:16 +0100, Jonathan Cameron wrote:
>> On Mon, 2 Sep 2024 18:04:51 +0200
>> Angelo Dureghello <adureghello@...libre.com> wrote:
>>
>>> On 31/08/24 1:34 PM, Jonathan Cameron wrote:
>>>> On Thu, 29 Aug 2024 14:32:01 +0200
>>>> Angelo Dureghello <adureghello@...libre.com> wrote:
>>>>
>>>>> From: Angelo Dureghello <adureghello@...libre.com>
>>>>>
>>>>> Extend DAC backend with new features required for the AXI driver
>>>>> version for the a3552r DAC.
>>>>>
>>>>> Signed-off-by: Angelo Dureghello <adureghello@...libre.com>
>>>> Hi Angelo
>>>> Minor comments inline.
>>>>>
>>>>> static int axi_dac_enable(struct iio_backend *back)
>>>>> @@ -460,7 +493,13 @@ static int axi_dac_data_source_set(struct
>>>>> iio_backend *back, unsigned int chan,
>>>>> case IIO_BACKEND_EXTERNAL:
>>>>> return regmap_update_bits(st->regmap,
>>>>>
>>>>> AXI_DAC_REG_CHAN_CNTRL_7(chan),
>>>>> - AXI_DAC_DATA_SEL,
>>>>> AXI_DAC_DATA_DMA);
>>>>> + AXI_DAC_DATA_SEL,
>>>>> + AXI_DAC_DATA_DMA);
>>>> Unrelated change. If you want to change this, separate patch.
>>> Thanks, fixed.
>>>>
>>>>> + case IIO_BACKEND_INTERNAL_RAMP_16:
>>>>> + return regmap_update_bits(st->regmap,
>>>>> +
>>>>> AXI_DAC_REG_CHAN_CNTRL_7(chan),
>>>>> + AXI_DAC_DATA_SEL,
>>>>> +
>>>>> AXI_DAC_DATA_INTERNAL_RAMP_16);
>>>>> default:
>>>>> return -EINVAL;
>>>>> }
>>>>> @@ -518,9 +557,204 @@ static int axi_dac_reg_access(struct iio_backend
>>>>> *back, unsigned int reg,
>>>>> return regmap_write(st->regmap, reg, writeval);
>>>>> }
>>>>>
>>>>> +
>>>>> +static int axi_dac_bus_reg_write(struct iio_backend *back,
>>>>> + u32 reg, void *val, size_t size)
>>>> Maybe just pass an unsigned int for val?
>>>> So follow what regmap does? You will still need the size, but it
>>>> will just be configuration related rather than affecting the type
>>>> of val.
>>>>
>>> void * was used since data size in the future may vary depending
>>> on the bus physical interface.
>>>
>> I doubt it will get bigger than u64. Passing void * is always
>> nasty if we can do something else and this is a register writing
>> operation. I'm yet to meet an ADC or similar with > 64 bit registers
>> (or even one with 64 bit ones!)
> I think the original thinking was to support thinks like appending crc to the
> register read/write. But even in that case, u32 for val might be enough. Not
> sure. Anyways, as you often say with the backend stuff, this is all in the
> kernel so I guess we can change it to unsigned int and change it in the future
> if we need to.
>
> Since you mentioned regmap, I also want to bring something that was discussed
> before the RFC. Basically we talked about having the backend registering it's
> own regmap_bus. Then we would either:
>
> 1) Have a specific get_regmap_bus() callback for the frontend to initialize a
> regmap on;
> 2) Pass this bus into the core and have a new frontend API like
> devm_iio_backend_regmap_init().
>
> Then, on top of the API already provided by regmap (like _update_bit()), the
> frontend could just use regmap independent of having a backend or not.
>
> The current API is likely more generic but tbh (and David and Angelo are aware
> of it) my preferred approach it to use the regmap_bus stuff. I just don't feel
> that strong about it :)
regmap idea seems really nice and a better style.
Honestly, if possible, would not go for it right now.
The main reason is that i am on this work from months and it would
require a quite
big rework (also rearranging more common code, retest, etc) while i am
trying to
finalize a first driver.
If you agree, this could come in a second "cleanup" patchset, but at
least i can
provide an initial support for ad3552r.
>>> Actually, a reg bus write involves several AXI regmap operations.
>>>>
>>>>> +{
>>>>> + struct axi_dac_state *st = iio_backend_get_priv(back);
>>>>> +
>>>>> + if (!st->bus_type)
>>>>> + return -EOPNOTSUPP;
>>>>> +
>>>>> + if (st->bus_type == AXI_DAC_BUS_TYPE_QSPI) {
>>>> As below, I'd use a switch and factor out this block as a separate
>>>> bus specific function.
>>> Ok, changed.
>>>>
>>>>> + int ret;
>>>>> + u32 ival;
>>>>> +
>>>>> + if (size != 1 && size != 2)
>>>>> + return -EINVAL;
>>>>> +
>>>>> + switch (size) {
>>>>> + case 1:
>>>>> + ival = FIELD_PREP(AXI_DAC_DATA_WR_8, *(u8
>>>>> *)val);
>>>>> + break;
>>>>> + case 2:
>>>>> + ival = FIELD_PREP(AXI_DAC_DATA_WR_16, *(u16
>>>>> *)val);
>>>>> + break;
>>>>> + default:
>>>>> + return -EINVAL;
>>>> Hopefully compiler won't need this and the above. I'd drop the size != 1..
>>>> check in favour of just doing it in this switch.
>>>>
>>> sure, done.
>>>
>>>
>>>>> + }
>>>>> +
>>>>> + ret = regmap_write(st->regmap, AXI_DAC_CNTRL_DATA_WR,
>>>>> ival);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + /*
>>>>> + * Both REG_CNTRL_2 and AXI_DAC_CNTRL_DATA_WR need to
>>>>> know
>>>>> + * the data size. So keeping data size control here
>>>>> only,
>>>>> + * since data size is mandatory for to the current
>>>>> transfer.
>>>>> + * DDR state handled separately by specific backend
>>>>> calls,
>>>>> + * generally all raw register writes are SDR.
>>>>> + */
>>>>> + if (size == 1)
>>>>> + ret = regmap_set_bits(st->regmap,
>>>>> AXI_DAC_REG_CNTRL_2,
>>>>> + AXI_DAC_SYMB_8B);
>>>>> + else
>>>>> + ret = regmap_clear_bits(st->regmap,
>>>>> AXI_DAC_REG_CNTRL_2,
>>>>> + AXI_DAC_SYMB_8B);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + ret = regmap_update_bits(st->regmap,
>>>>> AXI_DAC_REG_CUSTOM_CTRL,
>>>>> + AXI_DAC_ADDRESS,
>>>>> + FIELD_PREP(AXI_DAC_ADDRESS,
>>>>> reg));
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + ret = regmap_update_bits(st->regmap,
>>>>> AXI_DAC_REG_CUSTOM_CTRL,
>>>>> + AXI_DAC_TRANSFER_DATA,
>>>>> + AXI_DAC_TRANSFER_DATA);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + ret = regmap_read_poll_timeout(st->regmap,
>>>>> + AXI_DAC_REG_CUSTOM_CTRL,
>>>>> ival,
>>>>> + ival &
>>>>> AXI_DAC_TRANSFER_DATA,
>>>>> + 10, 100 * KILO);
>>>>> + if (ret)
>>>>> + return ret;
>>>>> +
>>>>> + return regmap_clear_bits(st->regmap,
>>>>> AXI_DAC_REG_CUSTOM_CTRL,
>>>>> + AXI_DAC_TRANSFER_DATA);
>>>>> + }
>>>>> +
>>>>> + return -EINVAL;
>>>>> +}
>>>>> +
>>>>> +static int axi_dac_bus_reg_read(struct iio_backend *back,
>>>>> + u32 reg, void *val, size_t size)
>>>> As for write, I'd just use an unsigned int * for val like
>>>> regmap does.
>>> Ok, so initial choice was unsigned int, further thinking of
>>> possible future busses drive the choice to void *.
>>>
>>> Let me know, i can switch to unsigned int in case.
>> I would just go with unsigned int or at a push u64 *
>>
>>>
>>>>
>>>>> +{
>>>>> + struct axi_dac_state *st = iio_backend_get_priv(back);
>>>>> +
>>>>> + if (!st->bus_type)
>>>>> + return -EOPNOTSUPP;
>>>>> +
>>>>> + if (st->bus_type == AXI_DAC_BUS_TYPE_QSPI) {
>>>> It got mentioned in binding review but if this isn't QSPI, even
>>>> if similar don't call it that.
>>> It's a bit difficult to find a different name, physically,
>>> it is a QSPI, 4 lanes + clock + cs, and datasheet is naming it Quad SPI.
>>> But looking the data protocol, it's a bit different.
>> is QSPI actually defined anywhere? I assumed it would be like
>> SPI for which everything is so flexible you can build whatever you like.
>>
>>> QSPI has instruction, address and data.
>>> Here we have just ADDR and DATA.
>>>
> I'm not sure the instruction is really relevant for this. From a quick look, it
> feels like something used for accessing external flash memory like spi-nors. So,
> I would not be surprised if things are just like Jonathan said and this is just
> flexible as spi (being that extra instruction field a protocol defined for flash
> memory - where one typically sees this interface)
>
> - Nuno Sá
regards,
Angelo
--
,,, Angelo Dureghello
:: :. BayLibre -runtime team- Developer
:`___:
`____:
Powered by blists - more mailing lists