ioc: Add reset GPIO
This commit is contained in:
parent
b23252df95
commit
101117d0bc
@ -1,18 +1,41 @@
|
|||||||
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
diff --git a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||||
index 5aff8ecc66cb..c8201e79dff3 100644
|
index c8201e79dff3..5407742acad6 100644
|
||||||
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
--- a/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||||
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
+++ b/arch/arm/boot/dts/sun8i-h3-orangepi-pc.dts
|
||||||
@@ -211,9 +211,12 @@
|
@@ -210,12 +210,22 @@ &uart0 {
|
||||||
|
status = "okay";
|
||||||
};
|
};
|
||||||
|
|
||||||
|
+&pio {
|
||||||
|
+ lw35ioc_pins: lw35ioc-pins {
|
||||||
|
+ pins = "PA10";
|
||||||
|
+ function = "gpio_out";
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
+
|
||||||
&uart1 {
|
&uart1 {
|
||||||
+ status = "okay";
|
status = "okay";
|
||||||
pinctrl-names = "default";
|
pinctrl-names = "default";
|
||||||
pinctrl-0 = <&uart1_pins>;
|
pinctrl-0 = <&uart1_pins>;
|
||||||
- status = "disabled";
|
lw35ioc@0 {
|
||||||
+ lw35ioc@0 {
|
compatible = "brother,lw35";
|
||||||
+ compatible = "brother,lw35";
|
+ pinctrl-names = "default";
|
||||||
+ };
|
+ pinctrl-0 = <&lw35ioc_pins>;
|
||||||
|
+ rst-gpios = <&pio 0 10 GPIO_ACTIVE_LOW>;
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
&uart2 {
|
@@ -242,3 +252,13 @@ &usbphy {
|
||||||
|
/* VBUS on USB host ports are always on */
|
||||||
|
status = "okay";
|
||||||
|
};
|
||||||
|
+
|
||||||
|
+&spi0 {
|
||||||
|
+ status = "okay";
|
||||||
|
+ lmg6202ulyt@0 {
|
||||||
|
+ compatible = "hitachi,lmg6202ulyt";
|
||||||
|
+ reg = <0x0>;
|
||||||
|
+ spi-max-frequency = <2000000>;
|
||||||
|
+ cs-gpios = <0>, <&pio 0 3 GPIO_ACTIVE_LOW>;
|
||||||
|
+ };
|
||||||
|
+};
|
||||||
|
@ -7,6 +7,7 @@
|
|||||||
#include <linux/serdev.h>
|
#include <linux/serdev.h>
|
||||||
#include <linux/types.h>
|
#include <linux/types.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
#include <linux/gpio/consumer.h>
|
||||||
|
|
||||||
// #define ENABLE_DEBUG ENABLE_DEBUG
|
// #define ENABLE_DEBUG ENABLE_DEBUG
|
||||||
|
|
||||||
@ -43,20 +44,25 @@ static int keycode_map[] = {
|
|||||||
KEY_SYSRQ
|
KEY_SYSRQ
|
||||||
};
|
};
|
||||||
|
|
||||||
enum lw35ioc_state {SYNC, TYPE, KEYBOARD, PRINTER};
|
enum lw35ioc_state {PASSIVE, PASSTHROUGH, ACTIVE};
|
||||||
|
|
||||||
|
enum lw35ioc_packet_state {SYNC, TYPE, KEYBOARD, PRINTER};
|
||||||
|
|
||||||
struct lw35ioc_packet {
|
struct lw35ioc_packet {
|
||||||
enum lw35ioc_state state;
|
enum lw35ioc_packet_state state;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct lw35ioc_priv {
|
struct lw35ioc_priv {
|
||||||
struct serdev_device *serdev;
|
struct serdev_device *serdev;
|
||||||
struct input_dev *input_dev;
|
struct input_dev *input_dev;
|
||||||
|
struct gpio_desc *gpio_rst; /* GPIO to reset both AVRs */
|
||||||
|
|
||||||
|
enum lw35ioc_state state;
|
||||||
struct lw35ioc_packet packet;
|
struct lw35ioc_packet packet;
|
||||||
};
|
};
|
||||||
|
|
||||||
static int lw35ioc_receive_buf(struct serdev_device *serdev,
|
|
||||||
|
static int lw35ioc_process_buf(struct serdev_device *serdev,
|
||||||
const unsigned char *data,
|
const unsigned char *data,
|
||||||
size_t count)
|
size_t count)
|
||||||
{
|
{
|
||||||
@ -107,6 +113,17 @@ static int lw35ioc_receive_buf(struct serdev_device *serdev,
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int lw35ioc_receive_buf(struct serdev_device *serdev,
|
||||||
|
const unsigned char *data,
|
||||||
|
size_t count)
|
||||||
|
{
|
||||||
|
struct lw35ioc_priv *priv = serdev_device_get_drvdata(serdev);
|
||||||
|
if (priv->state == ACTIVE)
|
||||||
|
return lw35ioc_process_buf(serdev, data, count);
|
||||||
|
|
||||||
|
return count; /* Pretend we read all data */
|
||||||
|
}
|
||||||
|
|
||||||
static void lw35ioc_write_wakeup(struct serdev_device *serdev)
|
static void lw35ioc_write_wakeup(struct serdev_device *serdev)
|
||||||
{
|
{
|
||||||
dev_info(&serdev->dev, "Write wakeup\n");
|
dev_info(&serdev->dev, "Write wakeup\n");
|
||||||
@ -118,6 +135,14 @@ static struct serdev_device_ops lw35ioc_serdev_ops = {
|
|||||||
.write_wakeup = lw35ioc_write_wakeup,
|
.write_wakeup = lw35ioc_write_wakeup,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void lw35ioc_set_hw_reset(struct serdev_device *serdev,
|
||||||
|
int reset_active)
|
||||||
|
{
|
||||||
|
struct lw35ioc_priv *priv = serdev_device_get_drvdata(serdev);
|
||||||
|
|
||||||
|
gpiod_set_value(priv->gpio_rst, !reset_active);
|
||||||
|
}
|
||||||
|
|
||||||
static int lw35ioc_probe(struct serdev_device *serdev)
|
static int lw35ioc_probe(struct serdev_device *serdev)
|
||||||
{
|
{
|
||||||
struct lw35ioc_priv *priv = NULL;
|
struct lw35ioc_priv *priv = NULL;
|
||||||
@ -128,6 +153,7 @@ static int lw35ioc_probe(struct serdev_device *serdev)
|
|||||||
|
|
||||||
printk(KERN_INFO "lw35ioc: probe\n");
|
printk(KERN_INFO "lw35ioc: probe\n");
|
||||||
|
|
||||||
|
/* Allocate memory */
|
||||||
priv = devm_kzalloc(&serdev->dev,
|
priv = devm_kzalloc(&serdev->dev,
|
||||||
sizeof(struct lw35ioc_priv),
|
sizeof(struct lw35ioc_priv),
|
||||||
GFP_KERNEL);
|
GFP_KERNEL);
|
||||||
@ -135,11 +161,13 @@ static int lw35ioc_probe(struct serdev_device *serdev)
|
|||||||
printk(KERN_ERR "lw35ioc: Not enough memory.\n");
|
printk(KERN_ERR "lw35ioc: Not enough memory.\n");
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
}
|
}
|
||||||
|
priv->state = PASSIVE;
|
||||||
priv->serdev = serdev;
|
priv->serdev = serdev;
|
||||||
priv->packet.state = SYNC;
|
priv->packet.state = SYNC;
|
||||||
serdev_device_set_drvdata(serdev, priv);
|
serdev_device_set_drvdata(serdev, priv);
|
||||||
serdev_device_set_client_ops(serdev, &lw35ioc_serdev_ops);
|
serdev_device_set_client_ops(serdev, &lw35ioc_serdev_ops);
|
||||||
|
|
||||||
|
/* Register input device */
|
||||||
input_dev = devm_input_allocate_device(&serdev->dev);
|
input_dev = devm_input_allocate_device(&serdev->dev);
|
||||||
if (!input_dev) {
|
if (!input_dev) {
|
||||||
dev_err(&serdev->dev, "Unable to allocate input device.\n");
|
dev_err(&serdev->dev, "Unable to allocate input device.\n");
|
||||||
@ -156,25 +184,37 @@ static int lw35ioc_probe(struct serdev_device *serdev)
|
|||||||
ret = input_register_device(input_dev);
|
ret = input_register_device(input_dev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&serdev->dev, "Unable to register input device.\n");
|
dev_err(&serdev->dev, "Unable to register input device.\n");
|
||||||
goto fail0;
|
goto fail_input;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = serdev_device_open(serdev);
|
ret = serdev_device_open(serdev);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&serdev->dev, "Unable to open device.\n");
|
dev_err(&serdev->dev, "Unable to open device.\n");
|
||||||
goto fail1;
|
goto fail_serdev;
|
||||||
}
|
}
|
||||||
|
|
||||||
speed = serdev_device_set_baudrate(serdev, speed);
|
speed = serdev_device_set_baudrate(serdev, speed);
|
||||||
dev_info(&serdev->dev, "Using baudrate: %u\n", speed);
|
dev_info(&serdev->dev, "Using baudrate: %u\n", speed);
|
||||||
|
|
||||||
|
/* Register GPIO */
|
||||||
|
priv->gpio_rst = gpiod_get_index(&serdev->dev,
|
||||||
|
"rst",
|
||||||
|
0,
|
||||||
|
GPIOD_OUT_LOW);
|
||||||
|
lw35ioc_set_hw_reset(serdev, 0);
|
||||||
|
|
||||||
|
if (IS_ERR(priv->gpio_rst)) {
|
||||||
|
dev_err(&serdev->dev, "Unable to get reset GPIO.\n");
|
||||||
|
ret = -ENODEV;
|
||||||
|
goto fail_gpio;
|
||||||
|
}
|
||||||
dev_info(&serdev->dev, "Loaded driver.\n");
|
dev_info(&serdev->dev, "Loaded driver.\n");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
fail_gpio:
|
||||||
fail1:
|
fail_serdev:
|
||||||
input_unregister_device(input_dev);
|
input_unregister_device(input_dev);
|
||||||
fail0:
|
fail_input:
|
||||||
devm_kfree(&serdev->dev, input_dev);
|
devm_kfree(&serdev->dev, input_dev);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@ -183,6 +223,8 @@ static void lw35ioc_remove(struct serdev_device *serdev)
|
|||||||
{
|
{
|
||||||
struct lw35ioc_priv *priv = serdev_device_get_drvdata(serdev);
|
struct lw35ioc_priv *priv = serdev_device_get_drvdata(serdev);
|
||||||
|
|
||||||
|
lw35ioc_set_hw_reset(serdev, 1);
|
||||||
|
gpiod_put(priv->gpio_rst);
|
||||||
serdev_device_close(priv->serdev);
|
serdev_device_close(priv->serdev);
|
||||||
input_unregister_device(priv->input_dev);
|
input_unregister_device(priv->input_dev);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user