Skip to content

Commit

Permalink
mfd: Add support for UP board CPLD/FPGA
Browse files Browse the repository at this point in the history
The UP Squared board <http://www.upboard.com> implements certain
features (pin control, onboard LEDs or CEC) through an on-board FPGA.

This mfd driver implements the line protocol to read and write registers
from the FPGA through regmap. The register address map is also included.

The UP boards come with a few FPGA-controlled onboard LEDs:
* UP Board: yellow, green, red
* UP Squared: blue, yellow, green, red

The UP Boards provide a few I/O pin headers (for both GPIO and
functions), including a 40-pin Raspberry Pi compatible header.

This patch implements support for the FPGA-based pin controller that
manages direction and enable state for those header pins.

Signed-off-by: Javier Arteaga <javier@emutex.com>
[merge various fixes]
Signed-off-by: Nicola Lunghi <nicola.lunghi@emutex.com>
  • Loading branch information
jbeta authored and Nicola Lunghi committed Sep 13, 2017
1 parent c06e8a9 commit b215ed9
Show file tree
Hide file tree
Showing 11 changed files with 1,380 additions and 0 deletions.
3 changes: 3 additions & 0 deletions arch/x86/configs/upboard_defconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1636,6 +1636,7 @@ CONFIG_SPI_SPIDEV=m
CONFIG_SPI_LOOPBACK_TEST=m
CONFIG_PPS_CLIENT_LDISC=m
CONFIG_PPS_CLIENT_PARPORT=m
CONFIG_PINCTRL_UPBOARD=m
CONFIG_PINCTRL_BAYTRAIL=y
CONFIG_PINCTRL_CHERRYVIEW=y
CONFIG_PINCTRL_BROXTON=y
Expand Down Expand Up @@ -1864,6 +1865,7 @@ CONFIG_MFD_MENF21BMC=m
CONFIG_MFD_VIPERBOARD=m
CONFIG_MFD_RTSX_PCI=m
CONFIG_MFD_RTSX_USB=m
CONFIG_MFD_UPBOARD_FPGA=m
CONFIG_MEDIA_SUPPORT=m
CONFIG_MEDIA_CAMERA_SUPPORT=y
CONFIG_MEDIA_ANALOG_TV_SUPPORT=y
Expand Down Expand Up @@ -2613,6 +2615,7 @@ CONFIG_LEDS_IS31FL319X=m
CONFIG_LEDS_IS31FL32XX=m
CONFIG_LEDS_BLINKM=m
CONFIG_LEDS_MLXCPLD=m
CONFIG_LEDS_UPBOARD=m
CONFIG_LEDS_TRIGGER_TIMER=m
CONFIG_LEDS_TRIGGER_ONESHOT=m
CONFIG_LEDS_TRIGGER_DISK=y
Expand Down
7 changes: 7 additions & 0 deletions drivers/leds/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,13 @@ config LEDS_MLXCPLD
This option enabled support for the LEDs on the Mellanox
boards. Say Y to enabled these.

config LEDS_UPBOARD
tristate "LED support for the UP board"
depends on LEDS_CLASS
depends on MFD_UPBOARD_FPGA
help
This option enables support for the UP board LEDs.

comment "LED Triggers"
source "drivers/leds/trigger/Kconfig"

Expand Down
1 change: 1 addition & 0 deletions drivers/leds/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ obj-$(CONFIG_LEDS_IS31FL319X) += leds-is31fl319x.o
obj-$(CONFIG_LEDS_IS31FL32XX) += leds-is31fl32xx.o
obj-$(CONFIG_LEDS_PM8058) += leds-pm8058.o
obj-$(CONFIG_LEDS_MLXCPLD) += leds-mlxcpld.o
obj-$(CONFIG_LEDS_UPBOARD) += leds-upboard.o

# LED SPI Drivers
obj-$(CONFIG_LEDS_DAC124S085) += leds-dac124s085.o
Expand Down
88 changes: 88 additions & 0 deletions drivers/leds/leds-upboard.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/*
* UP Board FPGA-based LED driver
*
* Copyright (c) 2017, Emutex Ltd. All rights reserved.
*
* Author: Javier Arteaga <javier@emutex.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/kernel.h>
#include <linux/leds.h>
#include <linux/mfd/upboard-fpga.h>
#include <linux/module.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>

struct upboard_led {
struct regmap_field *field;
struct led_classdev cdev;
};

static enum led_brightness upboard_led_brightness_get(struct led_classdev
*cdev)
{
struct upboard_led *led = container_of(cdev, struct upboard_led, cdev);
int brightness = 0;

regmap_field_read(led->field, &brightness);

return brightness;
};

static void upboard_led_brightness_set(struct led_classdev *cdev,
enum led_brightness brightness)
{
struct upboard_led *led = container_of(cdev, struct upboard_led, cdev);

regmap_field_write(led->field, brightness != LED_OFF);
};

static int __init upboard_led_probe(struct platform_device *pdev)
{
struct upboard_fpga * const fpga = dev_get_drvdata(pdev->dev.parent);
struct reg_field fldconf = {
.reg = UPFPGA_REG_FUNC_EN0,
};
struct upboard_led_data * const pdata = pdev->dev.platform_data;
struct upboard_led *led;

if (!fpga || !pdata)
return -EINVAL;

led = devm_kzalloc(&pdev->dev, sizeof(*led), GFP_KERNEL);
if (!led)
return -ENOMEM;

fldconf.lsb = pdata->bit;
fldconf.msb = pdata->bit;
led->field = devm_regmap_field_alloc(&pdev->dev, fpga->regmap, fldconf);
if (IS_ERR(led->field))
return PTR_ERR(led->field);

led->cdev.brightness_get = upboard_led_brightness_get;
led->cdev.brightness_set = upboard_led_brightness_set;
led->cdev.name = devm_kasprintf(&pdev->dev, GFP_KERNEL, "upboard:%s:",
pdata->colour);

if (!led->cdev.name)
return -ENOMEM;

return devm_led_classdev_register(&pdev->dev, &led->cdev);
};

static struct platform_driver upboard_led_driver = {
.driver = {
.name = "upboard-led",
},
};

module_platform_driver_probe(upboard_led_driver, upboard_led_probe);

MODULE_AUTHOR("Javier Arteaga <javier@emutex.com>");
MODULE_DESCRIPTION("UP Board LED driver");
MODULE_LICENSE("GPL v2");
MODULE_ALIAS("platform:upboard-led");
6 changes: 6 additions & 0 deletions drivers/mfd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1607,6 +1607,12 @@ config MFD_STW481X
in various ST Microelectronics and ST-Ericsson embedded
Nomadik series.

config MFD_UPBOARD_FPGA
tristate "Support for the UP board FPGA"
select MFD_CORE
help
Select this option to enable the UP and UP^2 on-board FPGA.

menu "Multimedia Capabilities Port drivers"
depends on ARCH_SA1100

Expand Down
2 changes: 2 additions & 0 deletions drivers/mfd/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -212,3 +212,5 @@ obj-$(CONFIG_MFD_MT6397) += mt6397-core.o
obj-$(CONFIG_MFD_INTEL_VUPORT) += intel-vuport.o

obj-$(CONFIG_MFD_ALTERA_A10SR) += altera-a10sr.o

obj-$(CONFIG_MFD_UPBOARD_FPGA) += upboard-fpga.o
Loading

4 comments on commit b215ed9

@andy-shev
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no go:

  1. leds driver is not needed, one can do it via ACPI (see meta-acpi Galileo Gen 2 example)
  2. MFD part is not needed in full, CPLD programming interface rather should be drivers/pinctrl/bitbang.c
  3. pin control driver needs refactoring because of above and perhaps more

@Dan-Lightsource
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@andy-shev

  1. The LEDs on the UP* boards cannot be driven directly by GPIOs, so I don't think the meta-acpi Galileo Gen2 example will work here. We have a separate LED controller implemented on an FPGA which we need to instruct, via a proprietary protocol, to turn individual LEDs on/off
  2. I would assume that drivers/pinctrl/bitbang.c would be a place to put a bit-banged implementation generic pinctrl bus protocol (if such a thing existed), for it to be consistent with examples like drivers/spi/spi-bitbang.c. Ours is a proprietary protocol, unforuntately, so I think it should be embodied in an UP-specific driver. It happens to be bit-banged over GPIOs now, but could potentially be driven over SPI or I2C in the future, so I don't think the bit-banged nature of the current implementation is too significant.
  3. Perhaps. We'll take another look at it anyway.

@jbeta
Copy link
Author

@jbeta jbeta commented on b215ed9 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(This patch was absolutely meant to be split and sent a series anyway. I'll make sure to rework this after the ongoing discussion.)

@andy-shev
Copy link

@andy-shev andy-shev commented on b215ed9 Jan 19, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. That's why we need a proper pin control (chained) driver for CPLD.
  2. Yeah, I realized that and put differently in email I sent earlier.
  3. Yep, let's do via email.

Please sign in to comment.