add dtbo for m4berry and m4zero

This commit is contained in:
August 2024-06-26 20:26:56 +08:00
parent 7581bba58e
commit 15c7800c4d
23 changed files with 739 additions and 40 deletions

View File

@ -8,11 +8,17 @@ dtbo-$(CONFIG_BOARD_BANANAPI_M4BERRY) += \
bpi-m4berry-ph-uart2.dtbo \
bpi-m4berry-uart5.dtbo \
bpi-m4berry-pwm1.dtbo \
bpi-m4berry-pwm1-beeper.dtbo \
bpi-m4berry-pwm1-fan.dtbo \
bpi-m4berry-spi1.dtbo \
bpi-m4berry-spi1-flash.dtbo \
bpi-m4berry-waveshare-tft24.dtbo \
bpi-m4berry-waveshare-tft35c.dtbo \
bpi-m4berry-spdifout.dtbo \
bpi-m4berry-i2smic-mems.dtbo \
bpi-m4berry-nxez-pcm512x-hifi.dtbo \
bpi-m4berry-waveshare-wm8960-hifi.dtbo
bpi-m4berry-waveshare-wm8960-hifi.dtbo \
bpi-m4berry-ds3231.dtbo
targets += $(dtbo-y)

View File

@ -0,0 +1,27 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&twi4>;
__overlay__ {
status = "okay";
/* rtc-ds1307.ko */
ds3231: rtc@68 {
status = "okay";
compatible = "ds3231";
reg = <0x68>;
};
};
};
fragment@1 {
target = <&rtc>;
__overlay__ {
status = "disabled";
};
};
};

View File

@ -0,0 +1,19 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&twi4>;
__overlay__ {
status = "okay";
at24@50 {
compatible = "at24,24c02";
reg = <0x50>;
pagesize = <8>;
//read-only;
};
};
};
};

View File

@ -0,0 +1,32 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&pwm>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&pwm1>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target-path = "/";
__overlay__ {
beeper: beeper {
compatible = "pwm-beeper";
pwms = <&pwm 1 1000000 0>;
status = "okay";
};
};
};
};

View File

@ -0,0 +1,77 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&pwm>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&pwm1>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&pwm1_pin_b>;
__overlay__ {
/* pull down for input mode when pwm disable */
bias-pull-down;
};
};
fragment@3 {
target-path = "/";
__overlay__ {
pwmfan: pwm-fan {
compatible = "pwm-fan";
pwms = <&pwm 1 10000 0>;
cooling-min-state = <0>;
cooling-max-state = <2>;
#cooling-cells = <2>;
cooling-levels = <0 150 230>;
status = "okay";
};
};
};
fragment@4 {
target = <&cpu_thermal>;
__overlay__ {
trips {
fan0: fan@0 {
temperature = <65000>;
hysteresis = <5000>;
type = "active";
};
fan1: fan@1 {
temperature = <80000>;
hysteresis = <5000>;
type = "active";
};
};
cooling-maps {
fan_cooling_map0 {
trip = <&fan0>;
cooling-device = <&pwmfan 0 1>;
};
fan_cooling_map1 {
trip = <&fan1>;
cooling-device = <&pwmfan 1 2>;
};
};
};
};
};

View File

@ -0,0 +1,22 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
spi1_cs_number = <1>;
spi1_cs_bitmap = <1>;
spiflash: w25q128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "w25q128", "jedec,spi-nor", "winbond,w25q128";
spi-max-frequency = <100000000>;
reg = <0>;
};
};
};
};

View File

@ -0,0 +1,28 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
spi1_cs_number = <1>;
spi1_cs_bitmap = <1>;
tft24: tft24@0 {
compatible = "ilitek,ili9341";
reg = <0>;
spi-max-frequency = <50000000>;
rotate = <90>;
bgr = <0>;
fps = <30>;
buswidth = <8>;
reset-gpios = <0x23 0x07 0x3 0x00>; //phy.13
dc-gpios = <0x23 0x06 0x1 0x00>; //phy.22
led-gpios = <0x23 0x06 0xb 0x00>; //phy.12
debug = <0>;
};
};
};
};

View File

@ -0,0 +1,60 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
spi1_cs_number = <2>;
spi1_cs_bitmap = <3>;
tft35c: tft35c@0 {
compatible = "ilitek,ili9486";
reg = <0>;
spi-max-frequency = <80000000>;
txbuflen = <32768>;
rotate = <90>;
bgr = <0>;
fps = <30>;
buswidth = <8>;
regwidth = <16>;
reset-gpios = <0x23 0x06 0x1 0x00>; //phy.22
dc-gpios = <0x23 0x06 0x9 0x00>; //phy.18
debug = <0>;
init = <0x10000f1 0x36 0x4 0x0 0x3c 0xf 0x8f
0x10000f2 0x18 0xa3 0x12 0x2 0xb2 0x12 0xff 0x10 0x0
0x10000f8 0x21 0x4
0x10000f9 0x0 0x8
0x1000036 0x8
0x10000b4 0x0
0x10000c1 0x41
0x10000c5 0x0 0x91 0x80 0x0
0x10000e0 0xf 0x1f 0x1c 0xc 0xf 0x8 0x48 0x98 0x37 0xa 0x13 0x4 0x11 0xd 0x0
0x10000e1 0xf 0x32 0x2e 0xb 0xd 0x5 0x47 0x75 0x37 0x6 0x10 0x3 0x24 0x20 0x0
0x100003a 0x55
0x1000011
0x1000036 0x28
0x20000ff
0x1000029>;
};
ads7846: ads7846@1 {
status = "okay";
compatible = "ti,ads7846";
spi-max-frequency = <2000000>;
reg = <1>;
pendown-gpio = <0x23 0x07 0x2 0x00>; //phy.11
ti,x-plate-ohms = /bits/ 16 <60>;
ti,pressure-max = /bits/ 16 <255>;
//linux,wakeup;
};
};
};
};

View File

@ -6,11 +6,15 @@ dtbo-$(CONFIG_BOARD_BANANAPI_M4ZERO) += \
bpi-m4zero-uart4.dtbo \
bpi-m4zero-uart5.dtbo \
bpi-m4zero-pwm2.dtbo \
bpi-m4zero-pwm2-beeper.dtbo \
bpi-m4zero-pwm2-fan.dtbo \
bpi-m4zero-spi1.dtbo \
bpi-m4zero-spi1-flash.dtbo \
bpi-m4zero-spdifout.dtbo \
bpi-m4zero-i2smic-mems.dtbo \
bpi-m4zero-nxez-pcm512x-hifi.dtbo \
bpi-m4zero-waveshare-wm8960-hifi.dtbo
bpi-m4zero-waveshare-wm8960-hifi.dtbo \
bpi-m4zero-ds3231.dtbo
targets += $(dtbo-y)
always := $(dtbo-y)

View File

@ -0,0 +1,27 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&twi0>;
__overlay__ {
status = "okay";
/* rtc-ds1307.ko */
ds3231: rtc@68 {
status = "okay";
compatible = "ds3231";
reg = <0x68>;
};
};
};
fragment@1 {
target = <&rtc>;
__overlay__ {
status = "disabled";
};
};
};

View File

@ -0,0 +1,32 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&pwm>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&pwm2>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target-path = "/";
__overlay__ {
beeper: beeper {
compatible = "pwm-beeper";
pwms = <&pwm 2 1000000 0>;
status = "okay";
};
};
};
};

View File

@ -0,0 +1,77 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&pwm>;
__overlay__ {
status = "okay";
};
};
fragment@1 {
target = <&pwm2>;
__overlay__ {
status = "okay";
};
};
fragment@2 {
target = <&pwm2_pin_b>;
__overlay__ {
/* pull down for input mode when pwm disable */
bias-pull-down;
};
};
fragment@3 {
target-path = "/";
__overlay__ {
pwmfan: pwm-fan {
compatible = "pwm-fan";
pwms = <&pwm 2 10000 0>;
cooling-min-state = <0>;
cooling-max-state = <2>;
#cooling-cells = <2>;
cooling-levels = <0 150 230>;
status = "okay";
};
};
};
fragment@4 {
target = <&cpu_thermal>;
__overlay__ {
trips {
fan0: fan@0 {
temperature = <65000>;
hysteresis = <5000>;
type = "active";
};
fan1: fan@1 {
temperature = <80000>;
hysteresis = <5000>;
type = "active";
};
};
cooling-maps {
fan_cooling_map0 {
trip = <&fan0>;
cooling-device = <&pwmfan 0 1>;
};
fan_cooling_map1 {
trip = <&fan1>;
cooling-device = <&pwmfan 1 2>;
};
};
};
};
};

View File

@ -11,7 +11,7 @@
};
fragment@1 {
target = <&pwm1>;
target = <&pwm2>;
__overlay__ {
status = "okay";

View File

@ -0,0 +1,22 @@
/dts-v1/;
/plugin/;
/ {
fragment@0 {
target = <&spi1>;
__overlay__ {
status = "okay";
spi1_cs_number = <1>;
spi1_cs_bitmap = <1>;
spiflash: w25q128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "w25q128", "jedec,spi-nor", "winbond,w25q128";
spi-max-frequency = <100000000>;
reg = <0>;
};
};
};
};

View File

@ -367,6 +367,12 @@
phandle = <0x7a>;
};
gpiomem {
compatible = "allwinner, gpiomem";
reg = <0x0 0x0300b000 0x0 0x400>; /* GPIO banks */
status = "okay";
};
soc@3000000 {
compatible = "simple-bus";
#address-cells = <0x2>;
@ -694,6 +700,7 @@
pwm-base = <0>;
sunxi-pwms = <&pwm0>, <&pwm1>, <&pwm2>, <&pwm3>,
<&pwm4>, <&pwm5>;
#pwm-cells = <3>;
status = "okay";
};
@ -1086,7 +1093,7 @@
};
spi1@1 {
pins = "PH9";
pins = "PH5", "PH9";
function = "spi1";
drive-strength = <0x14>;
bias-pull-up;
@ -1094,7 +1101,7 @@
};
spi1@2 {
pins = "PH6", "PH7", "PH8", "PH9";
pins = "PH5", "PH6", "PH7", "PH8", "PH9";
function = "gpio_in";
drive-strength = <0x14>;
phandle = <0x47>;
@ -1596,12 +1603,6 @@
pinctrl-names = "default", "sleep";
twi_drv_used = <0x1>;
phandle = <0xa0>;
eeprom@50 {
compatible = "atmel,24c16";
reg = <0x50>;
status = "disabled";
};
};
twi@5002400 {
@ -1837,15 +1838,6 @@
/*spi_dbi_enable = <0x0>;*/
phandle = <0xaa>;
spi_board1@0 {
device_type = "spi_board1";
compatible = "linux,spidev";
spi-max-frequency = <0x5f5e100>;
reg = <0x0>;
spi-rx-bus-width = <0x1>;
spi-tx-bus-width = <0x1>;
status = "disabled";
};
};
ts0@5060000 {
@ -2794,7 +2786,7 @@
thermal-zones {
cpu_thermal_zone {
cpu_thermal: cpu_thermal_zone {
polling-delay-passive = <0x1f4>;
polling-delay = <0x3e8>;
thermal-sensors = <0x72 0x2>;
@ -2825,7 +2817,7 @@
};
};
cooling-maps {
cpu_cooling_maps: cooling-maps {
map0 {
trip = <0x73>;
@ -2911,6 +2903,7 @@
reg_pio1_8 = "/pio-18";
reg_pio3_3 = "/pio-33";
dram = "/dram";
gpiomem = "/gpiomem";
soc = "/soc@3000000";
disp = "/soc@3000000/disp@1000000";
ve = "/soc@3000000/ve@1c0e000";

View File

@ -367,6 +367,12 @@
phandle = <0x7a>;
};
gpiomem {
compatible = "allwinner, gpiomem";
reg = <0x0 0x0300b000 0x0 0x400>; /* GPIO banks */
status = "okay";
};
soc@3000000 {
compatible = "simple-bus";
#address-cells = <0x2>;
@ -694,6 +700,7 @@
pwm-base = <0>;
sunxi-pwms = <&pwm0>, <&pwm1>, <&pwm2>, <&pwm3>,
<&pwm4>, <&pwm5>;
#pwm-cells = <3>;
status = "okay";
};
@ -744,6 +751,7 @@
status = "disabled";
};
/* ephy ac200 */
pwm5: pwm5@300a015 {
compatible = "allwinner,sunxi-pwm5";
reg = <0x0 0x0300a015 0x0 0x4>;
@ -1079,7 +1087,7 @@
};
spi1@1 {
pins = "PH9";
pins = "PH5", "PH9";
function = "spi1";
drive-strength = <0x14>;
bias-pull-up;
@ -1849,15 +1857,6 @@
/*spi_dbi_enable = <0x0>;*/
phandle = <0xaa>;
spi_board1@0 {
device_type = "spi_board1";
compatible = "linux,spidev";
spi-max-frequency = <0x5f5e100>;
reg = <0x0>;
spi-rx-bus-width = <0x1>;
spi-tx-bus-width = <0x1>;
status = "disabled";
};
};
ts0@5060000 {
@ -2821,7 +2820,7 @@
thermal-zones {
cpu_thermal_zone {
cpu_thermal: cpu_thermal_zone {
polling-delay-passive = <0x1f4>;
polling-delay = <0x3e8>;
thermal-sensors = <0x72 0x2>;
@ -2852,7 +2851,7 @@
};
};
cooling-maps {
cpu_cooling_maps: cooling-maps {
map0 {
trip = <0x73>;
@ -2938,6 +2937,7 @@
reg_pio1_8 = "/pio-18";
reg_pio3_3 = "/pio-33";
dram = "/dram";
gpiomem = "/gpiomem";
soc = "/soc@3000000";
disp = "/soc@3000000/disp@1000000";
ve = "/soc@3000000/ve@1c0e000";

View File

@ -2382,7 +2382,7 @@ CONFIG_USB_NET_CDCETHER=y
CONFIG_USB_NET_CDC_NCM=y
# CONFIG_USB_NET_HUAWEI_CDC_NCM is not set
# CONFIG_USB_NET_CDC_MBIM is not set
# CONFIG_USB_NET_DM9601 is not set
CONFIG_USB_NET_DM9601=m
# CONFIG_USB_NET_SR9700 is not set
# CONFIG_USB_NET_SR9800 is not set
# CONFIG_USB_NET_SMSC75XX is not set
@ -2766,7 +2766,7 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_AXP2101_PEK=y
CONFIG_INPUT_UINPUT=y
# CONFIG_INPUT_PCF8574 is not set
# CONFIG_INPUT_PWM_BEEPER is not set
CONFIG_INPUT_PWM_BEEPER=m
# CONFIG_INPUT_PWM_VIBRA is not set
# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
# CONFIG_INPUT_ADXL34X is not set
@ -2822,6 +2822,7 @@ CONFIG_TRACE_ROUTER=m
CONFIG_TRACE_SINK=m
CONFIG_NULL_TTY=m
CONFIG_LDISC_AUTOLOAD=y
CONFIG_DEVGPIOMEM=y
CONFIG_DEVMEM=y
#
@ -3331,7 +3332,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_OCC_P8_I2C is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_PMBUS is not set
# CONFIG_SENSORS_PWM_FAN is not set
CONFIG_SENSORS_PWM_FAN=m
# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SHT21 is not set
# CONFIG_SENSORS_SHT3x is not set

View File

@ -2766,7 +2766,7 @@ CONFIG_INPUT_MISC=y
CONFIG_INPUT_AXP2101_PEK=y
CONFIG_INPUT_UINPUT=y
# CONFIG_INPUT_PCF8574 is not set
# CONFIG_INPUT_PWM_BEEPER is not set
CONFIG_INPUT_PWM_BEEPER=m
# CONFIG_INPUT_PWM_VIBRA is not set
# CONFIG_INPUT_GPIO_ROTARY_ENCODER is not set
# CONFIG_INPUT_ADXL34X is not set
@ -2822,6 +2822,7 @@ CONFIG_TRACE_ROUTER=m
CONFIG_TRACE_SINK=m
CONFIG_NULL_TTY=m
CONFIG_LDISC_AUTOLOAD=y
CONFIG_DEVGPIOMEM=y
CONFIG_DEVMEM=y
#
@ -3331,7 +3332,7 @@ CONFIG_HWMON=y
# CONFIG_SENSORS_OCC_P8_I2C is not set
# CONFIG_SENSORS_PCF8591 is not set
# CONFIG_PMBUS is not set
# CONFIG_SENSORS_PWM_FAN is not set
CONFIG_SENSORS_PWM_FAN=m
# CONFIG_SENSORS_SHT15 is not set
# CONFIG_SENSORS_SHT21 is not set
# CONFIG_SENSORS_SHT3x is not set

View File

@ -7,6 +7,15 @@ menu "Character devices"
source "drivers/tty/Kconfig"
config DEVGPIOMEM
tristate "/dev/gpiomem rootless GPIO access via mmap()"
default y
help
Provides users with root-free access to the GPIO registers.
Calling mmap(/dev/gpiomem) will map the GPIO register page
to the user's pointer. This drvier can allow to access
gpio memory area in user account.
config DEVMEM
bool "/dev/mem virtual device support"
default y

View File

@ -3,6 +3,7 @@
# Makefile for the kernel character device drivers.
#
obj-$(CONFIG_DEVGPIOMEM) += gpiomem.o
obj-y += mem.o random.o
obj-$(CONFIG_TTY_PRINTK) += ttyprintk.o
obj-y += misc.o

248
drivers/char/gpiomem.c Normal file
View File

@ -0,0 +1,248 @@
/*
* linux/drivers/char/gpiomem.c
*
* GPIO memory device driver
*
* Creates a chardev /dev/gpiomem which will provide user access to
* the GPIO registers when it is mmap()'d.
* No longer need root for user GPIO access, but without relaxing permissions
* on /dev/mem.
*
* This driver is based on bcm2835-gpiomem.c in Raspberrypi's linux kernel 4.4:
* Written by Luke Wren <luke@raspberrypi.org>
* Copyright (c) 2015, Raspberry Pi (Trading) Ltd.
*/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/cdev.h>
#include <linux/pagemap.h>
#include <linux/io.h>
#include <linux/of.h>
#include <asm/io.h>
#define DEVICE_NAME "sunxi-gpiomem"
#define DRIVER_NAME "sunxi-gpiomem"
#define DEVICE_MINOR 0
struct regs_phys {
unsigned long start;
unsigned long end;
};
struct sunxi_gpiomem_instance {
struct regs_phys gpio_regs_phys[32];
int gpio_area_count;
struct device *dev;
};
static struct cdev sunxi_gpiomem_cdev;
static dev_t sunxi_gpiomem_devid;
static struct class *sunxi_gpiomem_class;
static struct device *sunxi_gpiomem_dev;
static struct sunxi_gpiomem_instance *inst;
static int sunxi_gpiomem_open(struct inode *inode, struct file *file)
{
int dev = iminor(inode);
int ret = 0;
dev_info(inst->dev, "gpiomem device opened.");
if (dev != DEVICE_MINOR) {
dev_err(inst->dev, "Unknown minor device: %d", dev);
ret = -ENXIO;
}
return ret;
}
static int sunxi_gpiomem_release(struct inode *inode, struct file *file)
{
int dev = iminor(inode);
int ret = 0;
if (dev != DEVICE_MINOR) {
dev_err(inst->dev, "Unknown minor device %d", dev);
ret = -ENXIO;
}
return ret;
}
static const struct vm_operations_struct sunxi_gpiomem_vm_ops = {
#ifdef CONFIG_HAVE_IOREMAP_PROT
.access = generic_access_phys
#endif
};
static int sunxi_gpiomem_mmap(struct file *file, struct vm_area_struct *vma)
{
int gpio_area = 0;
unsigned long start = vma->vm_pgoff << PAGE_SHIFT;
unsigned long end = start + vma->vm_end - vma->vm_start;
while (gpio_area < inst->gpio_area_count) {
if ((inst->gpio_regs_phys[gpio_area].start >= start) &&
(inst->gpio_regs_phys[gpio_area].end <= end))
goto found;
gpio_area++;
}
return -EACCES;
found:
vma->vm_page_prot = phys_mem_access_prot(file, vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot);
vma->vm_ops = &sunxi_gpiomem_vm_ops;
if (remap_pfn_range(vma, vma->vm_start,
vma->vm_pgoff,
vma->vm_end - vma->vm_start,
vma->vm_page_prot)) {
return -EAGAIN;
}
return 0;
}
static const struct file_operations
sunxi_gpiomem_fops = {
.owner = THIS_MODULE,
.open = sunxi_gpiomem_open,
.release = sunxi_gpiomem_release,
.mmap = sunxi_gpiomem_mmap,
};
static int sunxi_gpiomem_probe(struct platform_device *pdev)
{
int err = 0;
struct device *dev = &pdev->dev;
struct device_node *np = dev->of_node;
struct resource *res = NULL;
int i = 0;
/* Allocate buffers and instance data */
inst = kzalloc(sizeof(struct sunxi_gpiomem_instance), GFP_KERNEL);
if (!inst) {
err = -ENOMEM;
goto failed_inst_alloc;
}
inst->dev = dev;
inst->gpio_area_count = of_property_count_elems_of_size(np, "reg",
sizeof(u32)) / 4;
if (inst->gpio_area_count > 32 || inst->gpio_area_count <= 0) {
dev_err(inst->dev, "failed to get gpio register area.");
err = -EINVAL;
goto failed_inst_alloc;
}
dev_info(inst->dev, "Initialised: GPIO register area is %d",
inst->gpio_area_count);
for (i = 0; i < inst->gpio_area_count; ++i) {
res = platform_get_resource(pdev, IORESOURCE_MEM, i);
if (res) {
inst->gpio_regs_phys[i].start = res->start;
inst->gpio_regs_phys[i].end = res->end;
} else {
dev_err(inst->dev, "failed to get IO resource area %d", i);
err = -ENOENT;
goto failed_get_resource;
}
}
/* Create character device entries */
err = alloc_chrdev_region(&sunxi_gpiomem_devid,
DEVICE_MINOR, 1, DEVICE_NAME);
if (err != 0) {
dev_err(inst->dev, "unable to allocate device number");
goto failed_alloc_chrdev;
}
cdev_init(&sunxi_gpiomem_cdev, &sunxi_gpiomem_fops);
sunxi_gpiomem_cdev.owner = THIS_MODULE;
err = cdev_add(&sunxi_gpiomem_cdev, sunxi_gpiomem_devid, 1);
if (err != 0) {
dev_err(inst->dev, "unable to register device");
goto failed_cdev_add;
}
/* Create sysfs entries */
sunxi_gpiomem_class = class_create(THIS_MODULE, DEVICE_NAME);
err = IS_ERR(sunxi_gpiomem_class);
if (err)
goto failed_class_create;
sunxi_gpiomem_dev = device_create(sunxi_gpiomem_class, NULL,
sunxi_gpiomem_devid, NULL,
"gpiomem");
err = IS_ERR(sunxi_gpiomem_dev);
if (err)
goto failed_device_create;
for (i = 0; i < inst->gpio_area_count; ++i) {
dev_info(inst->dev,
"Initialised: Registers at start:0x%08lx end:0x%08lx size:0x%08lx",
inst->gpio_regs_phys[i].start,
inst->gpio_regs_phys[i].end,
inst->gpio_regs_phys[i].end - inst->gpio_regs_phys[i].start);
}
return 0;
failed_device_create:
class_destroy(sunxi_gpiomem_class);
failed_class_create:
cdev_del(&sunxi_gpiomem_cdev);
failed_cdev_add:
unregister_chrdev_region(sunxi_gpiomem_devid, 1);
failed_alloc_chrdev:
failed_get_resource:
kfree(inst);
failed_inst_alloc:
dev_err(inst->dev, "could not load sunxi_gpiomem");
return err;
}
static int sunxi_gpiomem_remove(struct platform_device *pdev)
{
struct device *dev = inst->dev;
kfree(inst);
device_destroy(sunxi_gpiomem_class, sunxi_gpiomem_devid);
class_destroy(sunxi_gpiomem_class);
cdev_del(&sunxi_gpiomem_cdev);
unregister_chrdev_region(sunxi_gpiomem_devid, 1);
dev_info(dev, "GPIO mem driver removed - OK");
return 0;
}
static const struct of_device_id sunxi_gpiomem_of_match[] = {
{.compatible = "allwinner, gpiomem",},
{ },
};
MODULE_DEVICE_TABLE(of, sunxi_gpiomem_of_match);
static struct platform_driver sunxi_gpiomem_driver = {
.driver = {
.name = DRIVER_NAME,
.owner = THIS_MODULE,
.of_match_table = sunxi_gpiomem_of_match,
},
.probe = sunxi_gpiomem_probe,
.remove = sunxi_gpiomem_remove,
};
module_platform_driver(sunxi_gpiomem_driver);
MODULE_ALIAS("platform:gpiomem");
MODULE_DESCRIPTION("Allwinner gpiomem driver for accessing GPIO from userspace");
MODULE_LICENSE("GPL");

View File

@ -1275,10 +1275,12 @@ static int ads7846_probe(struct spi_device *spi)
unsigned long irq_flags;
int err;
#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO)
if (!spi->irq) {
dev_dbg(&spi->dev, "no IRQ?\n");
dev_err(&spi->dev, "no IRQ?\n");
return -EINVAL;
}
#endif
/* don't exceed max specified sample rate */
if (spi->max_speed_hz > (125000 * SAMPLE_BITS)) {
@ -1402,15 +1404,23 @@ static int ads7846_probe(struct spi_device *spi)
if (IS_ERR(ts->reg)) {
err = PTR_ERR(ts->reg);
dev_err(&spi->dev, "unable to get regulator: %d\n", err);
#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO)
goto err_free_gpio;
#endif
}
err = regulator_enable(ts->reg);
if (err) {
dev_err(&spi->dev, "unable to enable regulator: %d\n", err);
#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO)
goto err_put_regulator;
#endif
}
#if defined(CONFIG_BOARD_BANANAPI_M4BERRY) || defined(CONFIG_BOARD_BANANAPI_M4ZERO)
spi->irq = gpio_to_irq(ts->gpio_pendown);
#endif
irq_flags = pdata->irq_flags ? : IRQF_TRIGGER_FALLING;
irq_flags |= IRQF_ONESHOT;
@ -1472,11 +1482,13 @@ static int ads7846_probe(struct spi_device *spi)
free_irq(spi->irq, ts);
err_disable_regulator:
regulator_disable(ts->reg);
#if !defined(CONFIG_BOARD_BANANAPI_M4BERRY) && !defined(CONFIG_BOARD_BANANAPI_M4ZERO)
err_put_regulator:
regulator_put(ts->reg);
err_free_gpio:
if (!ts->get_pendown_state)
gpio_free(ts->gpio_pendown);
#endif
err_cleanup_filter:
if (ts->filter_cleanup)
ts->filter_cleanup(ts->filter_data);

View File

@ -2482,6 +2482,7 @@ static const struct flash_info spi_nor_ids[] = {
{ "w25q80", INFO(0xef5014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25q80bl", INFO(0xef4014, 0, 64 * 1024, 16, SECT_4K) },
{ "w25q128", INFO(0xef4018, 0, 64 * 1024, 256, SECT_4K) },
{ "w25q128fv", INFO(0xffa00e, 0, 64 * 1024, 256, SECT_4K) },
{ "w25q256", INFO(0xef4019, 0, 64 * 1024, 512, SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },
{ "w25q256jvm", INFO(0xef7019, 0, 64 * 1024, 512,
SECT_4K | SPI_NOR_DUAL_READ | SPI_NOR_QUAD_READ) },