mirror of
https://github.com/hardkernel/linux.git
synced 2026-03-24 19:40:21 +09:00
ODROIDC: Add 1-Wire driver.
Conflicts: arch/arm/boot/dts/meson8b_odroidc.dts Change-Id: I646ca2c20e25218da630ce965a1c43efcde2fbed
This commit is contained in:
@@ -944,6 +944,14 @@
|
||||
dev_name = "pwm-ctrl";
|
||||
status = "ok";
|
||||
};
|
||||
|
||||
w1 {
|
||||
compatible = "w1-gpio";
|
||||
dev_name = "w1";
|
||||
status = "ok";
|
||||
gpios = "GPIOY_3";
|
||||
// linux,open-drain; // .is_open_drain = 1;
|
||||
};
|
||||
}; /* end of / */
|
||||
|
||||
/* vim: set ts=4 sw=4 tw=80:*/
|
||||
|
||||
@@ -2049,7 +2049,31 @@ CONFIG_GPIO_SYSFS=y
|
||||
#
|
||||
# USB GPIO expanders:
|
||||
#
|
||||
# CONFIG_W1 is not set
|
||||
CONFIG_W1=m
|
||||
|
||||
#
|
||||
# 1-wire Bus Masters
|
||||
#
|
||||
# CONFIG_W1_MASTER_DS2490 is not set
|
||||
# CONFIG_W1_MASTER_DS2482 is not set
|
||||
# CONFIG_W1_MASTER_DS1WM is not set
|
||||
CONFIG_W1_MASTER_GPIO=m
|
||||
|
||||
#
|
||||
# 1-wire Slaves
|
||||
#
|
||||
CONFIG_W1_SLAVE_THERM=m
|
||||
# CONFIG_W1_SLAVE_SMEM is not set
|
||||
# CONFIG_W1_SLAVE_DS2408 is not set
|
||||
# CONFIG_W1_SLAVE_DS2413 is not set
|
||||
# CONFIG_W1_SLAVE_DS2423 is not set
|
||||
# CONFIG_W1_SLAVE_DS2431 is not set
|
||||
# CONFIG_W1_SLAVE_DS2433 is not set
|
||||
# CONFIG_W1_SLAVE_DS2760 is not set
|
||||
# CONFIG_W1_SLAVE_DS2780 is not set
|
||||
# CONFIG_W1_SLAVE_DS2781 is not set
|
||||
# CONFIG_W1_SLAVE_DS28E04 is not set
|
||||
# CONFIG_W1_SLAVE_BQ27000 is not set
|
||||
CONFIG_POWER_SUPPLY=y
|
||||
# CONFIG_POWER_SUPPLY_DEBUG is not set
|
||||
# CONFIG_PDA_POWER is not set
|
||||
|
||||
@@ -2,6 +2,12 @@
|
||||
# Makefile for 1-wire bus master drivers.
|
||||
#
|
||||
|
||||
ifeq ($(CONFIG_MACH_MESON8B_ODROIDC),y)
|
||||
w1-gpio-objs := w1-gpio-aml.o
|
||||
else
|
||||
w1-gpio-objs := w1-gpio.o
|
||||
endif
|
||||
|
||||
obj-$(CONFIG_W1_MASTER_MATROX) += matrox_w1.o
|
||||
obj-$(CONFIG_W1_MASTER_DS2490) += ds2490.o
|
||||
obj-$(CONFIG_W1_MASTER_DS2482) += ds2482.o
|
||||
|
||||
236
drivers/w1/masters/w1-gpio-aml.c
Normal file
236
drivers/w1/masters/w1-gpio-aml.c
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* w1-gpio - GPIO w1 bus master driver
|
||||
*
|
||||
* Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
|
||||
*
|
||||
* 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/init.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/slab.h>
|
||||
#include <linux/w1-gpio.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/of_gpio.h>
|
||||
#include <linux/pinctrl/consumer.h>
|
||||
#include <linux/err.h>
|
||||
#include <linux/of.h>
|
||||
|
||||
#include <linux/amlogic/aml_gpio_consumer.h>
|
||||
|
||||
#include "../w1.h"
|
||||
#include "../w1_int.h"
|
||||
|
||||
#define MODULE_NAME "amlw1"
|
||||
|
||||
static int w1_gpio_pin = 0;
|
||||
static int w1_gpio_pullup = 0;
|
||||
|
||||
module_param(w1_gpio_pin,int,0644);
|
||||
MODULE_PARM_DESC(w1_gpio_pin,"\n odroid gpio number for 1-wire\n");
|
||||
|
||||
module_param(w1_gpio_pullup,int,0644);
|
||||
MODULE_PARM_DESC(w1_gpio_pullup,"\n odroid gpio number for 1-wire ext_pullup\n");
|
||||
|
||||
static void w1_gpio_write_bit_dir(void *data, u8 bit)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = data;
|
||||
|
||||
if (bit)
|
||||
amlogic_gpio_direction_input(pdata->pin, MODULE_NAME);
|
||||
else
|
||||
amlogic_gpio_direction_output(pdata->pin, 0, MODULE_NAME);
|
||||
}
|
||||
|
||||
static void w1_gpio_write_bit_val(void *data, u8 bit)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = data;
|
||||
|
||||
amlogic_set_value(pdata->pin, bit, MODULE_NAME);
|
||||
}
|
||||
|
||||
static u8 w1_gpio_read_bit(void *data)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = data;
|
||||
|
||||
return amlogic_get_value(pdata->pin, MODULE_NAME) ? 1 : 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
static struct of_device_id w1_gpio_dt_ids[] = {
|
||||
{ .compatible = "w1-gpio" },
|
||||
{}
|
||||
};
|
||||
MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
|
||||
#endif
|
||||
|
||||
static int w1_gpio_probe_dt(struct platform_device *pdev)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
|
||||
struct device_node *np = pdev->dev.of_node;
|
||||
|
||||
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
|
||||
if (!pdata)
|
||||
return -ENOMEM;
|
||||
|
||||
if (of_get_property(np, "linux,open-drain", NULL))
|
||||
pdata->is_open_drain = 1;
|
||||
|
||||
if(w1_gpio_pin)
|
||||
pdata->pin = w1_gpio_pin;
|
||||
else
|
||||
pdata->pin = of_get_gpio(np, 0);
|
||||
|
||||
pdata->ext_pullup_enable_pin = w1_gpio_pullup;
|
||||
pdev->dev.platform_data = pdata;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int w1_gpio_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct w1_bus_master *master;
|
||||
struct w1_gpio_platform_data *pdata;
|
||||
int err;
|
||||
|
||||
if (of_have_populated_dt()) {
|
||||
err = w1_gpio_probe_dt(pdev);
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "Failed to parse DT\n");
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
pdata = pdev->dev.platform_data;
|
||||
|
||||
if (!pdata) {
|
||||
dev_err(&pdev->dev, "No configuration data\n");
|
||||
return -ENXIO;
|
||||
}
|
||||
|
||||
master = kzalloc(sizeof(struct w1_bus_master), GFP_KERNEL);
|
||||
if (!master) {
|
||||
dev_err(&pdev->dev, "Out of memory\n");
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
err = amlogic_gpio_request(pdata->pin, MODULE_NAME);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "gpio_request (pin) failed\n");
|
||||
goto free_master;
|
||||
}
|
||||
|
||||
if(pdata->ext_pullup_enable_pin) {
|
||||
err = amlogic_gpio_request_one(pdata->ext_pullup_enable_pin,
|
||||
GPIOF_INIT_LOW, "w1 pullup");
|
||||
if (err < 0) {
|
||||
dev_err(&pdev->dev, "gpio_request_one "
|
||||
"(ext_pullup_enable_pin) failed\n");
|
||||
goto free_gpio;
|
||||
}
|
||||
}
|
||||
|
||||
master->data = pdata;
|
||||
master->read_bit = w1_gpio_read_bit;
|
||||
|
||||
if (pdata->is_open_drain) {
|
||||
amlogic_gpio_direction_output(pdata->pin, 1, MODULE_NAME);
|
||||
master->write_bit = w1_gpio_write_bit_val;
|
||||
} else {
|
||||
amlogic_gpio_direction_input(pdata->pin, MODULE_NAME);
|
||||
master->write_bit = w1_gpio_write_bit_dir;
|
||||
}
|
||||
|
||||
err = w1_add_master_device(master);
|
||||
if (err) {
|
||||
dev_err(&pdev->dev, "w1_add_master device failed\n");
|
||||
goto free_gpio_ext_pu;
|
||||
}
|
||||
|
||||
if (pdata->enable_external_pullup)
|
||||
pdata->enable_external_pullup(1);
|
||||
|
||||
if(pdata->ext_pullup_enable_pin)
|
||||
amlogic_set_value(pdata->ext_pullup_enable_pin, 1, MODULE_NAME);
|
||||
|
||||
platform_set_drvdata(pdev, master);
|
||||
|
||||
return 0;
|
||||
|
||||
free_gpio_ext_pu:
|
||||
if(pdata->ext_pullup_enable_pin)
|
||||
amlogic_gpio_free(pdata->ext_pullup_enable_pin, MODULE_NAME);
|
||||
free_gpio:
|
||||
amlogic_gpio_free(pdata->pin, MODULE_NAME);
|
||||
free_master:
|
||||
kfree(master);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
static int w1_gpio_remove(struct platform_device *pdev)
|
||||
{
|
||||
struct w1_bus_master *master = platform_get_drvdata(pdev);
|
||||
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (pdata->enable_external_pullup)
|
||||
pdata->enable_external_pullup(0);
|
||||
|
||||
if(pdata->ext_pullup_enable_pin)
|
||||
amlogic_set_value(pdata->ext_pullup_enable_pin, 0, MODULE_NAME);
|
||||
|
||||
w1_remove_master_device(master);
|
||||
amlogic_gpio_free(pdata->pin, MODULE_NAME);
|
||||
kfree(master);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_PM
|
||||
|
||||
static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (pdata->enable_external_pullup)
|
||||
pdata->enable_external_pullup(0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int w1_gpio_resume(struct platform_device *pdev)
|
||||
{
|
||||
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
|
||||
|
||||
if (pdata->enable_external_pullup)
|
||||
pdata->enable_external_pullup(1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else
|
||||
#define w1_gpio_suspend NULL
|
||||
#define w1_gpio_resume NULL
|
||||
#endif
|
||||
|
||||
static struct platform_driver w1_gpio_driver = {
|
||||
.driver = {
|
||||
.name = "w1-gpio",
|
||||
.owner = THIS_MODULE,
|
||||
.of_match_table = of_match_ptr(w1_gpio_dt_ids),
|
||||
},
|
||||
.probe = w1_gpio_probe,
|
||||
.remove = w1_gpio_remove,
|
||||
.suspend = w1_gpio_suspend,
|
||||
.resume = w1_gpio_resume,
|
||||
};
|
||||
|
||||
module_platform_driver(w1_gpio_driver);
|
||||
|
||||
MODULE_DESCRIPTION("GPIO w1 bus master driver for amlogic");
|
||||
MODULE_AUTHOR("Ville Syrjala <syrjala@sci.fi>");
|
||||
MODULE_LICENSE("GPL");
|
||||
@@ -54,28 +54,29 @@ static void w1_send_slave(struct w1_master *dev, u64 rn)
|
||||
struct w1_netlink_msg *hdr = (struct w1_netlink_msg *)(msg + 1);
|
||||
struct w1_netlink_cmd *cmd = (struct w1_netlink_cmd *)(hdr + 1);
|
||||
int avail;
|
||||
u64 *data;
|
||||
|
||||
/* update kernel slave list */
|
||||
w1_slave_found(dev, rn);
|
||||
|
||||
avail = dev->priv_size - cmd->len;
|
||||
|
||||
if (avail > 8) {
|
||||
u64 *data = (void *)(cmd + 1) + cmd->len;
|
||||
if (avail < 8) {
|
||||
msg->ack++;
|
||||
cn_netlink_send(msg, 0, GFP_KERNEL);
|
||||
|
||||
*data = rn;
|
||||
cmd->len += 8;
|
||||
hdr->len += 8;
|
||||
msg->len += 8;
|
||||
return;
|
||||
msg->len = sizeof(struct w1_netlink_msg) +
|
||||
sizeof(struct w1_netlink_cmd);
|
||||
hdr->len = sizeof(struct w1_netlink_cmd);
|
||||
cmd->len = 0;
|
||||
}
|
||||
|
||||
msg->ack++;
|
||||
cn_netlink_send(msg, 0, GFP_KERNEL);
|
||||
data = (void *)(cmd + 1) + cmd->len;
|
||||
|
||||
msg->len = sizeof(struct w1_netlink_msg) + sizeof(struct w1_netlink_cmd);
|
||||
hdr->len = sizeof(struct w1_netlink_cmd);
|
||||
cmd->len = 0;
|
||||
*data = rn;
|
||||
cmd->len += 8;
|
||||
hdr->len += 8;
|
||||
msg->len += 8;
|
||||
}
|
||||
|
||||
static int w1_process_search_command(struct w1_master *dev, struct cn_msg *msg,
|
||||
|
||||
Reference in New Issue
Block a user