[PATCH 1/2] spi: rockchip: add support for "cs-gpios" dts property
jeffy
jeffy.chen at rock-chips.com
Mon Jun 12 01:26:07 PDT 2017
Hi Shawn,
On 06/12/2017 03:15 PM, Shawn Lin wrote:
> Hi Jeffy,
>
> On 2017/6/12 14:14, Jeffy Chen wrote:
>> Support using "cs-gpios" property to specify cs gpios.
>>
>> Signed-off-by: Jeffy Chen <jeffy.chen at rock-chips.com>
>> ---
>>
>> .../devicetree/bindings/spi/spi-rockchip.txt | 2 +
>> drivers/spi/spi-rockchip.c | 52
>> ++++++++++++++++++++++
>> 2 files changed, 54 insertions(+)
>>
>> diff --git a/Documentation/devicetree/bindings/spi/spi-rockchip.txt
>> b/Documentation/devicetree/bindings/spi/spi-rockchip.txt
>> index 83da493..02171b2 100644
>> --- a/Documentation/devicetree/bindings/spi/spi-rockchip.txt
>> +++ b/Documentation/devicetree/bindings/spi/spi-rockchip.txt
>
> The changes for doc should be another patch, and...
but i saw others didn't separate them:
cf9e478 spi: sh-msiof: Add slave mode support
23e291c spi: rockchip: support "sleep" pin configuration
>
>> @@ -17,6 +17,7 @@ Required Properties:
>> region.
>> - interrupts: The interrupt number to the cpu. The interrupt
>> specifier format
>> depends on the interrupt controller.
>> +- cs-gpios : Specifies the gpio pins to be used for chipselects.
>
> It's not a required property, otherwise how other boards work as your
> patch 2 only add this for rk3399-gru.
oops, i will fix it.
>
>> - clocks: Must contain an entry for each entry in clock-names.
>> - clock-names: Shall be "spiclk" for the transfer-clock, and
>> "apb_pclk" for
>> the peripheral clock.
>> @@ -48,6 +49,7 @@ Example:
>> #address-cells = <1>;
>> #size-cells = <0>;
>> interrupts = <GIC_SPI 44 IRQ_TYPE_LEVEL_HIGH>;
>> + cs-gpios = <&gpio2 23 GPIO_ACTIVE_HIGH>;
>> clocks = <&cru SCLK_SPI0>, <&cru PCLK_SPI0>;
>> clock-names = "spiclk", "apb_pclk";
>> pinctrl-0 = <&spi1_pins>;
>> diff --git a/drivers/spi/spi-rockchip.c b/drivers/spi/spi-rockchip.c
>> index acf31f3..04694e1 100644
>> --- a/drivers/spi/spi-rockchip.c
>> +++ b/drivers/spi/spi-rockchip.c
>> @@ -15,6 +15,7 @@
>> #include <linux/clk.h>
>> #include <linux/dmaengine.h>
>> +#include <linux/gpio.h>
>> #include <linux/module.h>
>> #include <linux/of.h>
>> #include <linux/pinctrl/consumer.h>
>> @@ -201,6 +202,10 @@ struct rockchip_spi {
>> struct dma_slave_caps dma_caps;
>> };
>> +struct rockchip_spi_data {
>> + bool cs_gpio_requested;
>> +};
>> +
>
> Could you fold cs_gpio_requested into struct rockchip_spi?
>
>> static inline void spi_enable_chip(struct rockchip_spi *rs, int enable)
>> {
>> writel_relaxed((enable ? 1 : 0), rs->regs + ROCKCHIP_SPI_SSIENR);
>> @@ -297,6 +302,50 @@ static void rockchip_spi_set_cs(struct spi_device
>> *spi, bool enable)
>> pm_runtime_put_sync(rs->dev);
>> }
>> +static int rockchip_spi_setup(struct spi_device *spi)
>> +{
>> + int ret = 0;
>> + unsigned long flags = (spi->mode & SPI_CS_HIGH) ?
>> + GPIOF_OUT_INIT_LOW : GPIOF_OUT_INIT_HIGH;
>> + struct rockchip_spi_data *data = spi_get_ctldata(spi);
>> +
>> + if (!gpio_is_valid(spi->cs_gpio))
>> + return 0;
>
> return -EINVAL?
i think we can still support the original way, which means no "cs-gpios"
and do nothing in setup.
>
>> +
>> + if (!data) {
>> + data = kzalloc(sizeof(*data), GFP_KERNEL);
>> + if (!data)
>> + return -ENOMEM;
>> + spi_set_ctldata(spi, data);
>> + }
>> +
>> + if (!data->cs_gpio_requested) {
>> + ret = gpio_request_one(spi->cs_gpio, flags,
>> + dev_name(&spi->dev));
>> + if (!ret)
>> + data->cs_gpio_requested = 1;
>> + } else
>> + ret = gpio_direction_output(spi->cs_gpio, flags);
>
> need brace around 'else' statement. Also I don't see data used
> elsewhere, so you need these code above.
ok.
and the cs_gpio_requested is to mark cs_gpio requested, because the
setup func might be called multiple times, we only need to request gpio
at the first time.
>
>> +
>> + if (ret < 0)
>> + dev_err(&spi->dev, "Failed to setup cs gpio(%d): %d\n",
>> + spi->cs_gpio, ret);
>> +
>> + return ret;
>> +}
>> +
>> +static void rockchip_spi_cleanup(struct spi_device *spi)
>> +{
>> + struct rockchip_spi_data *data = spi_get_ctldata(spi);
>> +
>> + if (data) {
>> + if (data->cs_gpio_requested)
>> + gpio_free(spi->cs_gpio);
>> + kfree(data);
>> + spi_set_ctldata(spi, NULL);
>> + }
>> +}
>> +
>> static int rockchip_spi_prepare_message(struct spi_master *master,
>> struct spi_message *msg)
>> {
>> @@ -744,11 +793,14 @@ static int rockchip_spi_probe(struct
>> platform_device *pdev)
>> master->bits_per_word_mask = SPI_BPW_MASK(16) | SPI_BPW_MASK(8);
>> master->set_cs = rockchip_spi_set_cs;
>> + master->setup = rockchip_spi_setup;
>> + master->cleanup = rockchip_spi_cleanup;
>> master->prepare_message = rockchip_spi_prepare_message;
>> master->unprepare_message = rockchip_spi_unprepare_message;
>> master->transfer_one = rockchip_spi_transfer_one;
>> master->max_transfer_size = rockchip_spi_max_transfer_size;
>> master->handle_err = rockchip_spi_handle_err;
>> + master->flags = SPI_MASTER_GPIO_SS;
>> rs->dma_tx.ch = dma_request_chan(rs->dev, "tx");
>> if (IS_ERR(rs->dma_tx.ch)) {
>>
>
>
>
More information about the Linux-rockchip
mailing list