[PATCH 1/2] spi: rockchip: add support for "cs-gpios" dts property

Shawn Lin shawn.lin at rock-chips.com
Mon Jun 12 00:15:18 PDT 2017


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...

> @@ -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.

>   - 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?

> +
> +	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.

> +
> +	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-arm-kernel mailing list