Closed phmarek closed 7 years ago
What's missing is a way to parameterise DT node/property names as well as values. Without that you need one overlay for each concurrent w1 bus - something we've already seen with the two mcp2515 overlays.
This is a patch for 10 fixes bus-number 1wire busses with dt overlay and dynamic bind/unbind support and some other special addons.
there is also a bug with devm_kzalloc and 1wire. See https://groups.google.com/forum/#!topic/linux.kernel/xFzSWZZr_Gg
dt sample: dtoverlay=w1-gpio-10 dtparam=pullup1=y dtparam=pullup2=y dtparam=pullup3=y dtparam=pullup4=y dtparam=pullup5=y dtparam=pullup6=y dtparam=pullup7=y dtparam=pullup8=y dtparam=pullup9=y dtparam=pullup10=y dtparam=bus1=1 dtparam=bus2=2 dtparam=bus3=3 dtparam=bus4=4 dtparam=bus5=5 dtparam=bus6=6 dtparam=bus7=7 dtparam=bus8=8 dtparam=bus9=9 dtparam=bus10=10
diff --git a/arch/arm/boot/dts/overlays/Makefile b/arch/arm/boot/dts/overlays/Makefile
index f1af1ee..4fd0926 100644
--- a/arch/arm/boot/dts/overlays/Makefile
+++ b/arch/arm/boot/dts/overlays/Makefile
@@ -68,6 +68,7 @@ dtb-$(RPI_DT_OVERLAYS) += vc4-kms-v3d-overlay.dtb
dtb-$(RPI_DT_OVERLAYS) += vga666-overlay.dtb
dtb-$(RPI_DT_OVERLAYS) += w1-gpio-overlay.dtb
dtb-$(RPI_DT_OVERLAYS) += w1-gpio-pullup-overlay.dtb
+dtb-$(RPI_DT_OVERLAYS) += w1-gpio-10-overlay.dtb
dtb-$(RPI_DT_OVERLAYS) += wittypi-overlay.dtb
targets += dtbs dtbs_install
diff --git a/arch/arm/boot/dts/overlays/w1-gpio-10-overlay.dts b/arch/arm/boot/dts/overlays/w1-gpio-10-overlay.dts
new file mode 100644
index 0000000..071b3c3
--- /dev/null
+++ b/arch/arm/boot/dts/overlays/w1-gpio-10-overlay.dts
@@ -0,0 +1,223 @@
+// Definitions for w1-gpio module (without external pullup)
+/dts-v1/;
+/plugin/;
+
+/ {
+ compatible = "brcm,bcm2708";
+
+ fragment@0 {
+ target-path = "/";
+
+ __overlay__ {
+
+ w1_1: onewire@1 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_1_pins>;
+ gpios = <&gpio 4 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <1>;
+ status = "okay";
+ };
+
+ w1_2: onewire@2 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_2_pins>;
+ gpios = <&gpio 17 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <2>;
+ status = "okay";
+ };
+
+ w1_3: onewire@3 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_3_pins>;
+ gpios = <&gpio 18 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <3>;
+ status = "okay";
+ };
+
+ w1_4: onewire@4 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_4_pins>;
+ gpios = <&gpio 27 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <4>;
+ status = "okay";
+ };
+
+ w1_5: onewire@5 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_5_pins>;
+ gpios = <&gpio 22 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <5>;
+ status = "okay";
+ };
+
+ w1_6: onewire@6 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_6_pins>;
+ gpios = <&gpio 23 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <6>;
+ status = "okay";
+ };
+
+ w1_7: onewire@7 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_7_pins>;
+ gpios = <&gpio 24 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <7>;
+ status = "okay";
+ };
+
+ w1_8: onewire@8 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_8_pins>;
+ gpios = <&gpio 10 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <8>;
+ status = "okay";
+ };
+
+ w1_9: onewire@9 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_9_pins>;
+ gpios = <&gpio 9 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <9>;
+ status = "okay";
+ };
+
+ w1_10: onewire@10 {
+ compatible = "w1-gpio";
+ pinctrl-names = "default";
+ pinctrl-0 = <&w1_10_pins>;
+ gpios = <&gpio 25 0>;
+ rpi,parasitic-power = <0>;
+ bus,id = <10>;
+ status = "okay";
+ };
+ };
+ };
+
+ fragment@1 {
+ target = <&gpio>;
+
+ __overlay__ {
+
+ w1_1_pins: w1_1_pins {
+ brcm,pins = <4>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_2_pins: w1_pins {
+ brcm,pins = <17>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_3_pins: w1_3_pins {
+ brcm,pins = <18>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_4_pins: w1_4_pins {
+ brcm,pins = <27>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_5_pins: w1_5_pins {
+ brcm,pins = <22>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_6_pins: w1_6_pins {
+ brcm,pins = <23>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_7_pins: w1_7_pins {
+ brcm,pins = <24>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_8_pins: w1_8_pins {
+ brcm,pins = <10>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_9_pins: w1_9_pins {
+ brcm,pins = <9>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+
+ w1_10_pins: w1_10_pins {
+ brcm,pins = <25>;
+ brcm,function = <0>; // in (initially)
+ brcm,pull = <0>; // off
+ };
+ };
+ };
+
+ __overrides__ {
+ gpiopin1 = <&w1_1>,"gpios:4",
+ <&w1_1_pins>,"brcm,pins:0";
+ pullup1 = <&w1_1>,"rpi,parasitic-power:0";
+
+ gpiopin2 = <&w1_2>,"gpios:17",
+ <&w1_2_pins>,"brcm,pins:0";
+ pullup2 = <&w1_2>,"rpi,parasitic-power:0";
+
+ gpiopin3 = <&w1_3>,"gpios:18",
+ <&w1_3_pins>,"brcm,pins:0";
+ pullup3 = <&w1_3>,"rpi,parasitic-power:0";
+
+ gpiopin4 = <&w1_4>,"gpios:27",
+ <&w1_4_pins>,"brcm,pins:0";
+ pullup4 = <&w1_4>,"rpi,parasitic-power:0";
+
+ gpiopin5 = <&w1_5>,"gpios:22",
+ <&w1_5_pins>,"brcm,pins:0";
+ pullup5 = <&w1_5>,"rpi,parasitic-power:0";
+
+ gpiopin6 = <&w1_6>,"gpios:23",
+ <&w1_6_pins>,"brcm,pins:0";
+ pullup6 = <&w1_6>,"rpi,parasitic-power:0";
+
+ gpiopin7 = <&w1_7>,"gpios:24",
+ <&w1_7_pins>,"brcm,pins:0";
+ pullup7 = <&w1_7>,"rpi,parasitic-power:0";
+
+ gpiopin8 = <&w1_8>,"gpios:10",
+ <&w1_8_pins>,"brcm,pins:0";
+ pullup8 = <&w1_8>,"rpi,parasitic-power:0";
+
+ gpiopin9 = <&w1_9>,"gpios:9",
+ <&w1_9_pins>,"brcm,pins:0";
+ pullup9 = <&w1_9>,"rpi,parasitic-power:0";
+
+ gpiopin10 = <&w1_10>,"gpios:25",
+ <&w1_10_pins>,"brcm,pins:0";
+ pullup10 = <&w1_10>,"rpi,parasitic-power:0";
+ };
+};
diff --git a/arch/arm/mach-bcm2708/bcm2708.c b/arch/arm/mach-bcm2708/bcm2708.c
index 1b9c3be..037a887 100644
--- a/arch/arm/mach-bcm2708/bcm2708.c
+++ b/arch/arm/mach-bcm2708/bcm2708.c
@@ -80,9 +80,28 @@
#define DMA_MASK_BITS_COMMON 32
// use GPIO 4 for the one-wire GPIO pin, if enabled
-#define W1_GPIO 4
+#define W1_GPIO1 4
+#define W1_GPIO2 17
+#define W1_GPIO3 18
+#define W1_GPIO4 27
+#define W1_GPIO5 22
+#define W1_GPIO6 23
+#define W1_GPIO7 24
+#define W1_GPIO8 10
+#define W1_GPIO9 9
+#define W1_GPIO10 25
+
// ensure one-wire GPIO pullup is disabled by default
-#define W1_PULLUP -1
+#define W1_PULLUP1 -1
+#define W1_PULLUP2 -1
+#define W1_PULLUP3 -1
+#define W1_PULLUP4 -1
+#define W1_PULLUP5 -1
+#define W1_PULLUP6 -1
+#define W1_PULLUP7 -1
+#define W1_PULLUP8 -1
+#define W1_PULLUP9 -1
+#define W1_PULLUP10 -1
/* command line parameters */
static unsigned boardrev, serial;
@@ -90,8 +109,26 @@ static unsigned uart_clock = UART0_CLOCK;
static unsigned disk_led_gpio = 16;
static unsigned disk_led_active_low = 1;
static unsigned reboot_part = 0;
-static unsigned w1_gpio_pin = W1_GPIO;
-static unsigned w1_gpio_pullup = W1_PULLUP;
+static unsigned w1_gpio_pin = W1_GPIO1;
+static unsigned w1_gpio_pin1 = W1_GPIO2;
+static unsigned w1_gpio_pin2 = W1_GPIO3;
+static unsigned w1_gpio_pin3 = W1_GPIO4;
+static unsigned w1_gpio_pin4 = W1_GPIO5;
+static unsigned w1_gpio_pin5 = W1_GPIO6;
+static unsigned w1_gpio_pin6 = W1_GPIO7;
+static unsigned w1_gpio_pin7 = W1_GPIO8;
+static unsigned w1_gpio_pin8 = W1_GPIO9;
+static unsigned w1_gpio_pin9 = W1_GPIO10;
+static unsigned w1_gpio_pullup = W1_PULLUP1;
+static unsigned w1_gpio_pullup1 = W1_PULLUP2;
+static unsigned w1_gpio_pullup2 = W1_PULLUP3;
+static unsigned w1_gpio_pullup3 = W1_PULLUP4;
+static unsigned w1_gpio_pullup4 = W1_PULLUP5;
+static unsigned w1_gpio_pullup5 = W1_PULLUP6;
+static unsigned w1_gpio_pullup6 = W1_PULLUP7;
+static unsigned w1_gpio_pullup7 = W1_PULLUP8;
+static unsigned w1_gpio_pullup8 = W1_PULLUP9;
+static unsigned w1_gpio_pullup9 = W1_PULLUP10;
static bool vc_i2c_override = false;
static int pps_gpio_pin = -1;
@@ -315,16 +352,124 @@ static struct platform_device bcm2708_dmaengine_device = {
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
static struct w1_gpio_platform_data w1_gpio_pdata = {
- .pin = W1_GPIO,
- .ext_pullup_enable_pin = W1_PULLUP,
+ .pin = W1_GPIO1,
+ .ext_pullup_enable_pin = W1_PULLUP1,
.is_open_drain = 0,
};
static struct platform_device w1_device = {
.name = "w1-gpio",
- .id = -1,
+ .id = 1,
.dev.platform_data = &w1_gpio_pdata,
};
+
+static struct w1_gpio_platform_data w1_gpio_pdata1 = {
+ .pin = W1_GPIO2,
+ .ext_pullup_enable_pin = W1_PULLUP2,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device1 = {
+ .name = "w1-gpio",
+ .id = 2,
+ .dev.platform_data = &w1_gpio_pdata1,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata2 = {
+ .pin = W1_GPIO3,
+ .ext_pullup_enable_pin = W1_PULLUP3,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device2 = {
+ .name = "w1-gpio",
+ .id = 3,
+ .dev.platform_data = &w1_gpio_pdata2,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata3 = {
+ .pin = W1_GPIO4,
+ .ext_pullup_enable_pin = W1_PULLUP4,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device3 = {
+ .name = "w1-gpio",
+ .id = 4,
+ .dev.platform_data = &w1_gpio_pdata3,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata4 = {
+ .pin = W1_GPIO5,
+ .ext_pullup_enable_pin = W1_PULLUP5,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device4 = {
+ .name = "w1-gpio",
+ .id = 5,
+ .dev.platform_data = &w1_gpio_pdata4,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata5 = {
+ .pin = W1_GPIO6,
+ .ext_pullup_enable_pin = W1_PULLUP6,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device5 = {
+ .name = "w1-gpio",
+ .id = 6,
+ .dev.platform_data = &w1_gpio_pdata5,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata6 = {
+ .pin = W1_GPIO7,
+ .ext_pullup_enable_pin = W1_PULLUP7,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device6 = {
+ .name = "w1-gpio",
+ .id = 7,
+ .dev.platform_data = &w1_gpio_pdata6,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata7 = {
+ .pin = W1_GPIO8,
+ .ext_pullup_enable_pin = W1_PULLUP8,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device7 = {
+ .name = "w1-gpio",
+ .id = 8,
+ .dev.platform_data = &w1_gpio_pdata7,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata8 = {
+ .pin = W1_GPIO9,
+ .ext_pullup_enable_pin = W1_PULLUP9,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device8 = {
+ .name = "w1-gpio",
+ .id = 9,
+ .dev.platform_data = &w1_gpio_pdata8,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata9 = {
+ .pin = W1_GPIO10,
+ .ext_pullup_enable_pin = W1_PULLUP10,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device9 = {
+ .name = "w1-gpio",
+ .id = 10,
+ .dev.platform_data = &w1_gpio_pdata9,
+};
#endif
static struct pps_gpio_platform_data pps_gpio_info = {
@@ -898,8 +1043,35 @@ void __init bcm2708_init(void)
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
w1_gpio_pdata.pin = w1_gpio_pin;
- w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
+ w1_gpio_pdata1.pin = w1_gpio_pin1;
+ w1_gpio_pdata2.pin = w1_gpio_pin2;
+ w1_gpio_pdata3.pin = w1_gpio_pin3;
+ w1_gpio_pdata4.pin = w1_gpio_pin4;
+ w1_gpio_pdata5.pin = w1_gpio_pin5;
+ w1_gpio_pdata6.pin = w1_gpio_pin6;
+ w1_gpio_pdata7.pin = w1_gpio_pin7;
+ w1_gpio_pdata8.pin = w1_gpio_pin8;
+ w1_gpio_pdata9.pin = w1_gpio_pin9;
+ w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
+ w1_gpio_pdata1.ext_pullup_enable_pin = w1_gpio_pullup1;
+ w1_gpio_pdata2.ext_pullup_enable_pin = w1_gpio_pullup2;
+ w1_gpio_pdata3.ext_pullup_enable_pin = w1_gpio_pullup3;
+ w1_gpio_pdata4.ext_pullup_enable_pin = w1_gpio_pullup4;
+ w1_gpio_pdata5.ext_pullup_enable_pin = w1_gpio_pullup5;
+ w1_gpio_pdata6.ext_pullup_enable_pin = w1_gpio_pullup6;
+ w1_gpio_pdata7.ext_pullup_enable_pin = w1_gpio_pullup7;
+ w1_gpio_pdata8.ext_pullup_enable_pin = w1_gpio_pullup8;
+ w1_gpio_pdata9.ext_pullup_enable_pin = w1_gpio_pullup9;
bcm_register_device_dt(&w1_device);
+ bcm_register_device_dt(&w1_device1);
+ bcm_register_device_dt(&w1_device2);
+ bcm_register_device_dt(&w1_device3);
+ bcm_register_device_dt(&w1_device4);
+ bcm_register_device_dt(&w1_device5);
+ bcm_register_device_dt(&w1_device6);
+ bcm_register_device_dt(&w1_device7);
+ bcm_register_device_dt(&w1_device8);
+ bcm_register_device_dt(&w1_device9);
#endif
bcm_register_device_dt(&bcm2708_fb_device);
bcm_register_device_dt(&bcm2708_usb_device);
@@ -1155,7 +1327,25 @@ module_param(disk_led_gpio, uint, 0644);
module_param(disk_led_active_low, uint, 0644);
module_param(reboot_part, uint, 0644);
module_param(w1_gpio_pin, uint, 0644);
+module_param(w1_gpio_pin1, uint, 0644);
+module_param(w1_gpio_pin2, uint, 0644);
+module_param(w1_gpio_pin3, uint, 0644);
+module_param(w1_gpio_pin4, uint, 0644);
+module_param(w1_gpio_pin5, uint, 0644);
+module_param(w1_gpio_pin6, uint, 0644);
+module_param(w1_gpio_pin7, uint, 0644);
+module_param(w1_gpio_pin8, uint, 0644);
+module_param(w1_gpio_pin9, uint, 0644);
module_param(w1_gpio_pullup, uint, 0644);
+module_param(w1_gpio_pullup1, uint, 0644);
+module_param(w1_gpio_pullup2, uint, 0644);
+module_param(w1_gpio_pullup3, uint, 0644);
+module_param(w1_gpio_pullup4, uint, 0644);
+module_param(w1_gpio_pullup5, uint, 0644);
+module_param(w1_gpio_pullup6, uint, 0644);
+module_param(w1_gpio_pullup7, uint, 0644);
+module_param(w1_gpio_pullup8, uint, 0644);
+module_param(w1_gpio_pullup9, uint, 0644);
module_param(vc_i2c_override, bool, 0644);
MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral.");
module_param(pps_gpio_pin, int, 0644);
diff --git a/arch/arm/mach-bcm2709/bcm2709.c b/arch/arm/mach-bcm2709/bcm2709.c
index e1934dc..c914044 100644
--- a/arch/arm/mach-bcm2709/bcm2709.c
+++ b/arch/arm/mach-bcm2709/bcm2709.c
@@ -82,9 +82,28 @@
#define DMA_MASK_BITS_COMMON 32
// use GPIO 4 for the one-wire GPIO pin, if enabled
-#define W1_GPIO 4
+#define W1_GPIO1 4
+#define W1_GPIO2 17
+#define W1_GPIO3 18
+#define W1_GPIO4 27
+#define W1_GPIO5 22
+#define W1_GPIO6 23
+#define W1_GPIO7 24
+#define W1_GPIO8 10
+#define W1_GPIO9 9
+#define W1_GPIO10 25
+
// ensure one-wire GPIO pullup is disabled by default
-#define W1_PULLUP -1
+#define W1_PULLUP1 -1
+#define W1_PULLUP2 -1
+#define W1_PULLUP3 -1
+#define W1_PULLUP4 -1
+#define W1_PULLUP5 -1
+#define W1_PULLUP6 -1
+#define W1_PULLUP7 -1
+#define W1_PULLUP8 -1
+#define W1_PULLUP9 -1
+#define W1_PULLUP10 -1
/* command line parameters */
static unsigned boardrev, serial;
@@ -92,8 +111,26 @@ static unsigned uart_clock = UART0_CLOCK;
static unsigned disk_led_gpio = 16;
static unsigned disk_led_active_low = 1;
static unsigned reboot_part = 0;
-static unsigned w1_gpio_pin = W1_GPIO;
-static unsigned w1_gpio_pullup = W1_PULLUP;
+static unsigned w1_gpio_pin = W1_GPIO1;
+static unsigned w1_gpio_pin1 = W1_GPIO2;
+static unsigned w1_gpio_pin2 = W1_GPIO3;
+static unsigned w1_gpio_pin3 = W1_GPIO4;
+static unsigned w1_gpio_pin4 = W1_GPIO5;
+static unsigned w1_gpio_pin5 = W1_GPIO6;
+static unsigned w1_gpio_pin6 = W1_GPIO7;
+static unsigned w1_gpio_pin7 = W1_GPIO8;
+static unsigned w1_gpio_pin8 = W1_GPIO9;
+static unsigned w1_gpio_pin9 = W1_GPIO10;
+static unsigned w1_gpio_pullup = W1_PULLUP1;
+static unsigned w1_gpio_pullup1 = W1_PULLUP2;
+static unsigned w1_gpio_pullup2 = W1_PULLUP3;
+static unsigned w1_gpio_pullup3 = W1_PULLUP4;
+static unsigned w1_gpio_pullup4 = W1_PULLUP5;
+static unsigned w1_gpio_pullup5 = W1_PULLUP6;
+static unsigned w1_gpio_pullup6 = W1_PULLUP7;
+static unsigned w1_gpio_pullup7 = W1_PULLUP8;
+static unsigned w1_gpio_pullup8 = W1_PULLUP9;
+static unsigned w1_gpio_pullup9 = W1_PULLUP10;
static bool vc_i2c_override = false;
static int pps_gpio_pin = -1;
unsigned force_core;
@@ -326,16 +363,124 @@ static struct platform_device bcm2708_dmaengine_device = {
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
static struct w1_gpio_platform_data w1_gpio_pdata = {
- .pin = W1_GPIO,
- .ext_pullup_enable_pin = W1_PULLUP,
+ .pin = W1_GPIO1,
+ .ext_pullup_enable_pin = W1_PULLUP1,
.is_open_drain = 0,
};
static struct platform_device w1_device = {
.name = "w1-gpio",
- .id = -1,
+ .id = 1,
.dev.platform_data = &w1_gpio_pdata,
};
+
+static struct w1_gpio_platform_data w1_gpio_pdata1 = {
+ .pin = W1_GPIO2,
+ .ext_pullup_enable_pin = W1_PULLUP2,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device1 = {
+ .name = "w1-gpio",
+ .id = 2,
+ .dev.platform_data = &w1_gpio_pdata1,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata2 = {
+ .pin = W1_GPIO3,
+ .ext_pullup_enable_pin = W1_PULLUP3,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device2 = {
+ .name = "w1-gpio",
+ .id = 3,
+ .dev.platform_data = &w1_gpio_pdata2,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata3 = {
+ .pin = W1_GPIO4,
+ .ext_pullup_enable_pin = W1_PULLUP4,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device3 = {
+ .name = "w1-gpio",
+ .id = 4,
+ .dev.platform_data = &w1_gpio_pdata3,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata4 = {
+ .pin = W1_GPIO5,
+ .ext_pullup_enable_pin = W1_PULLUP5,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device4 = {
+ .name = "w1-gpio",
+ .id = 5,
+ .dev.platform_data = &w1_gpio_pdata4,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata5 = {
+ .pin = W1_GPIO6,
+ .ext_pullup_enable_pin = W1_PULLUP6,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device5 = {
+ .name = "w1-gpio",
+ .id = 6,
+ .dev.platform_data = &w1_gpio_pdata5,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata6 = {
+ .pin = W1_GPIO7,
+ .ext_pullup_enable_pin = W1_PULLUP7,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device6 = {
+ .name = "w1-gpio",
+ .id = 7,
+ .dev.platform_data = &w1_gpio_pdata6,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata7 = {
+ .pin = W1_GPIO8,
+ .ext_pullup_enable_pin = W1_PULLUP8,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device7 = {
+ .name = "w1-gpio",
+ .id = 8,
+ .dev.platform_data = &w1_gpio_pdata7,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata8 = {
+ .pin = W1_GPIO9,
+ .ext_pullup_enable_pin = W1_PULLUP9,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device8 = {
+ .name = "w1-gpio",
+ .id = 9,
+ .dev.platform_data = &w1_gpio_pdata8,
+};
+
+static struct w1_gpio_platform_data w1_gpio_pdata9 = {
+ .pin = W1_GPIO10,
+ .ext_pullup_enable_pin = W1_PULLUP10,
+ .is_open_drain = 0,
+};
+
+static struct platform_device w1_device9 = {
+ .name = "w1-gpio",
+ .id = 10,
+ .dev.platform_data = &w1_gpio_pdata9,
+};
#endif
static struct pps_gpio_platform_data pps_gpio_info = {
@@ -919,8 +1064,35 @@ void __init bcm2709_init(void)
#if defined(CONFIG_W1_MASTER_GPIO) || defined(CONFIG_W1_MASTER_GPIO_MODULE)
w1_gpio_pdata.pin = w1_gpio_pin;
+ w1_gpio_pdata1.pin = w1_gpio_pin1;
+ w1_gpio_pdata2.pin = w1_gpio_pin2;
+ w1_gpio_pdata3.pin = w1_gpio_pin3;
+ w1_gpio_pdata4.pin = w1_gpio_pin4;
+ w1_gpio_pdata5.pin = w1_gpio_pin5;
+ w1_gpio_pdata6.pin = w1_gpio_pin6;
+ w1_gpio_pdata7.pin = w1_gpio_pin7;
+ w1_gpio_pdata8.pin = w1_gpio_pin8;
+ w1_gpio_pdata9.pin = w1_gpio_pin9;
w1_gpio_pdata.ext_pullup_enable_pin = w1_gpio_pullup;
+ w1_gpio_pdata1.ext_pullup_enable_pin = w1_gpio_pullup1;
+ w1_gpio_pdata2.ext_pullup_enable_pin = w1_gpio_pullup2;
+ w1_gpio_pdata3.ext_pullup_enable_pin = w1_gpio_pullup3;
+ w1_gpio_pdata4.ext_pullup_enable_pin = w1_gpio_pullup4;
+ w1_gpio_pdata5.ext_pullup_enable_pin = w1_gpio_pullup5;
+ w1_gpio_pdata6.ext_pullup_enable_pin = w1_gpio_pullup6;
+ w1_gpio_pdata7.ext_pullup_enable_pin = w1_gpio_pullup7;
+ w1_gpio_pdata8.ext_pullup_enable_pin = w1_gpio_pullup8;
+ w1_gpio_pdata9.ext_pullup_enable_pin = w1_gpio_pullup9;
bcm_register_device_dt(&w1_device);
+ bcm_register_device_dt(&w1_device1);
+ bcm_register_device_dt(&w1_device2);
+ bcm_register_device_dt(&w1_device3);
+ bcm_register_device_dt(&w1_device4);
+ bcm_register_device_dt(&w1_device5);
+ bcm_register_device_dt(&w1_device6);
+ bcm_register_device_dt(&w1_device7);
+ bcm_register_device_dt(&w1_device8);
+ bcm_register_device_dt(&w1_device9);
#endif
bcm_register_device_dt(&bcm2708_fb_device);
bcm_register_device_dt(&bcm2708_usb_device);
@@ -1325,7 +1497,25 @@ module_param(disk_led_gpio, uint, 0644);
module_param(disk_led_active_low, uint, 0644);
module_param(reboot_part, uint, 0644);
module_param(w1_gpio_pin, uint, 0644);
+module_param(w1_gpio_pin1, uint, 0644);
+module_param(w1_gpio_pin2, uint, 0644);
+module_param(w1_gpio_pin3, uint, 0644);
+module_param(w1_gpio_pin4, uint, 0644);
+module_param(w1_gpio_pin5, uint, 0644);
+module_param(w1_gpio_pin6, uint, 0644);
+module_param(w1_gpio_pin7, uint, 0644);
+module_param(w1_gpio_pin8, uint, 0644);
+module_param(w1_gpio_pin9, uint, 0644);
module_param(w1_gpio_pullup, uint, 0644);
+module_param(w1_gpio_pullup1, uint, 0644);
+module_param(w1_gpio_pullup2, uint, 0644);
+module_param(w1_gpio_pullup3, uint, 0644);
+module_param(w1_gpio_pullup4, uint, 0644);
+module_param(w1_gpio_pullup5, uint, 0644);
+module_param(w1_gpio_pullup6, uint, 0644);
+module_param(w1_gpio_pullup7, uint, 0644);
+module_param(w1_gpio_pullup8, uint, 0644);
+module_param(w1_gpio_pullup9, uint, 0644);
module_param(vc_i2c_override, bool, 0644);
MODULE_PARM_DESC(vc_i2c_override, "Allow the use of VC's I2C peripheral.");
module_param(pps_gpio_pin, int, 0644);
diff --git a/drivers/w1/masters/w1-gpio.c b/drivers/w1/masters/w1-gpio.c
index 2240f32..1d367f6 100644
--- a/drivers/w1/masters/w1-gpio.c
+++ b/drivers/w1/masters/w1-gpio.c
@@ -1,4 +1,4 @@
-/*
+ /*
* w1-gpio - GPIO w1 bus master driver
*
* Copyright (C) 2007 Ville Syrjala <syrjala@sci.fi>
@@ -98,22 +98,29 @@ static const struct of_device_id w1_gpio_dt_ids[] = {
MODULE_DEVICE_TABLE(of, w1_gpio_dt_ids);
#endif
-static int w1_gpio_probe_dt(struct platform_device *pdev)
+static struct w1_gpio_platform_data *w1_gpio_probe_dt(struct platform_device *pdev)
{
struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
struct device_node *np = pdev->dev.of_node;
int gpio;
u32 value;
+ if (pdata)
+ return pdata;
+
pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
if (!pdata)
- return -ENOMEM;
+ return ERR_PTR(-ENOMEM);
if (of_get_property(np, "linux,open-drain", NULL))
pdata->is_open_drain = 1;
if (of_property_read_u32(np, "rpi,parasitic-power", &value) == 0)
pdata->parasitic_power = (value != 0);
+
+ if (of_property_read_u32(np, "bus,id", &value) == 0)
+ if( value != 0)
+ pdev->id = value;
gpio = of_get_gpio(np, 0);
if (gpio < 0) {
@@ -122,19 +129,17 @@ static int w1_gpio_probe_dt(struct platform_device *pdev)
"Failed to parse gpio property for data pin (%d)\n",
gpio);
- return gpio;
+ return ERR_PTR(gpio);
}
pdata->pin = gpio;
gpio = of_get_gpio(np, 1);
if (gpio == -EPROBE_DEFER)
- return gpio;
+ return ERR_PTR(gpio);
/* ignore other errors as the pullup gpio is optional */
pdata->ext_pullup_enable_pin = (gpio >= 0) ? gpio : -1;
- pdev->dev.platform_data = pdata;
-
- return 0;
+ return pdata;
}
static int w1_gpio_probe(struct platform_device *pdev)
@@ -143,19 +148,16 @@ static int w1_gpio_probe(struct platform_device *pdev)
struct w1_gpio_platform_data *pdata = pdev->dev.platform_data;
int err;
- if(pdata == NULL) {
- if (of_have_populated_dt()) {
- err = w1_gpio_probe_dt(pdev);
- if (err < 0)
- return err;
- }
- }
-
- pdata = dev_get_platdata(&pdev->dev);
+ if (of_have_populated_dt())
+ pdata = w1_gpio_probe_dt(pdev);
+ else
+ pdata = dev_get_platdata(&pdev->dev);
- if (!pdata) {
- dev_err(&pdev->dev, "No configuration data\n");
- return -ENXIO;
+ if (IS_ERR_OR_NULL(pdata)) {
+ dev_err(&pdev->dev, "No configuration data or configuration failed\n");
+ if (!pdata)
+ return -ENXIO;
+ return PTR_ERR(pdata);
}
master = devm_kzalloc(&pdev->dev, sizeof(struct w1_bus_master),
@@ -165,10 +167,13 @@ static int w1_gpio_probe(struct platform_device *pdev)
return -ENOMEM;
}
+ /*
w1_gpio_pin_orig = pdata->pin;
w1_gpio_pullup_pin_orig = pdata->ext_pullup_enable_pin;
w1_gpio_pullup_orig = pdata->parasitic_power;
+ */
+ /* collides with device tree!
if(gpio_is_valid(w1_gpio_pin)) {
pdata->pin = w1_gpio_pin;
pdata->ext_pullup_enable_pin = -1;
@@ -178,8 +183,9 @@ static int w1_gpio_probe(struct platform_device *pdev)
if(gpio_is_valid(w1_gpio_pullup_pin)) {
pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin;
}
+ */
- dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power);
+ dev_info(&pdev->dev, "gpio pin %d, external pullup pin %d, parasitic power %d, bus id %d\n", pdata->pin, pdata->ext_pullup_enable_pin, pdata->parasitic_power, pdev->id);
err = devm_gpio_request(&pdev->dev, pdata->pin, "w1");
if (err) {
@@ -199,6 +205,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
}
master->data = pdata;
+ master->id = pdev->id;
master->read_bit = w1_gpio_read_bit;
if (pdata->is_open_drain) {
@@ -238,7 +245,7 @@ static int w1_gpio_probe(struct platform_device *pdev)
static int w1_gpio_remove(struct platform_device *pdev)
{
struct w1_bus_master *master = platform_get_drvdata(pdev);
- struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct w1_gpio_platform_data *pdata = master->data;
if (pdata->enable_external_pullup)
pdata->enable_external_pullup(0);
@@ -248,9 +255,11 @@ static int w1_gpio_remove(struct platform_device *pdev)
w1_remove_master_device(master);
+ /*
pdata->pin = w1_gpio_pin_orig;
pdata->ext_pullup_enable_pin = w1_gpio_pullup_pin_orig;
pdata->parasitic_power = w1_gpio_pullup_orig;
+ */
return 0;
}
@@ -259,7 +268,8 @@ static int w1_gpio_remove(struct platform_device *pdev)
static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)
{
- struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct w1_bus_master *master = platform_get_drvdata(pdev);
+ struct w1_gpio_platform_data *pdata = master->data;
if (pdata->enable_external_pullup)
pdata->enable_external_pullup(0);
@@ -269,7 +279,8 @@ static int w1_gpio_suspend(struct platform_device *pdev, pm_message_t state)
static int w1_gpio_resume(struct platform_device *pdev)
{
- struct w1_gpio_platform_data *pdata = dev_get_platdata(&pdev->dev);
+ struct w1_bus_master *master = platform_get_drvdata(pdev);
+ struct w1_gpio_platform_data *pdata = master->data;
if (pdata->enable_external_pullup)
pdata->enable_external_pullup(1);
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index 181f41c..d69d0cb 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -310,6 +310,34 @@ static ssize_t w1_master_attribute_show_pointer(struct device *dev, struct devic
return count;
}
+static ssize_t w1_master_attribute_show_shortcircuit(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct w1_master *md = dev_to_w1_master(dev);
+ ssize_t count;
+
+ mutex_lock(&md->mutex);
+ count = sprintf(buf, "%d\n", md->shortcircuit);
+ mutex_unlock(&md->mutex);
+
+ return count;
+}
+
+static ssize_t w1_master_attribute_show_presence(struct device *dev,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct w1_master *md = dev_to_w1_master(dev);
+ ssize_t count;
+
+ mutex_lock(&md->mutex);
+ count = sprintf(buf, "%d\n", md->presence);
+ mutex_unlock(&md->mutex);
+
+ return count;
+}
+
static ssize_t w1_master_attribute_show_timeout(struct device *dev, struct device_attribute *attr, char *buf)
{
ssize_t count;
@@ -544,6 +572,8 @@ static W1_MASTER_ATTR_RW(max_slave_count, S_IRUGO | S_IWUSR | S_IWGRP);
static W1_MASTER_ATTR_RO(attempts, S_IRUGO);
static W1_MASTER_ATTR_RO(timeout, S_IRUGO);
static W1_MASTER_ATTR_RO(pointer, S_IRUGO);
+static W1_MASTER_ATTR_RO(shortcircuit, S_IRUGO);
+static W1_MASTER_ATTR_RO(presence, S_IRUGO);
static W1_MASTER_ATTR_RW(search, S_IRUGO | S_IWUSR | S_IWGRP);
static W1_MASTER_ATTR_RW(pullup, S_IRUGO | S_IWUSR | S_IWGRP);
static W1_MASTER_ATTR_RW(add, S_IRUGO | S_IWUSR | S_IWGRP);
@@ -557,6 +587,8 @@ static struct attribute *w1_master_default_attrs[] = {
&w1_master_attribute_attempts.attr,
&w1_master_attribute_timeout.attr,
&w1_master_attribute_pointer.attr,
+ &w1_master_attribute_shortcircuit.attr,
+ &w1_master_attribute_presence.attr,
&w1_master_attribute_search.attr,
&w1_master_attribute_pullup.attr,
&w1_master_attribute_add.attr,
@@ -939,6 +971,7 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
int i, slave_count = 0;
int last_zero, last_device;
int search_bit, desc_bit;
+ int result;
u8 triplet_ret = 0;
search_bit = 0;
@@ -960,11 +993,19 @@ void w1_search(struct w1_master *dev, u8 search_type, w1_slave_found_callback cb
* Return 0 - device(s) present, 1 - no devices present.
*/
mutex_lock(&dev->bus_mutex);
- if (w1_reset_bus(dev)) {
+ result = w1_reset_bus(dev);
+ if( result) {
mutex_unlock(&dev->bus_mutex);
+ dev->presence = 0;
+ if( result == 2)
+ dev->shortcircuit = 1;
+ else
+ dev->shortcircuit = 0;
dev_dbg(&dev->dev, "No devices present on the wire.\n");
break;
}
+ dev->shortcircuit = 0;
+ dev->presence = 1;
/* Do fast search on single slave bus */
if (dev->max_slave_count == 1) {
diff --git a/drivers/w1/w1.h b/drivers/w1/w1.h
index 881d728..3568109 100644
--- a/drivers/w1/w1.h
+++ b/drivers/w1/w1.h
@@ -179,6 +179,11 @@ struct w1_bus_master
void (*search)(void *, struct w1_master *,
u8, w1_slave_found_callback);
+
+ /**
+ * Gpio-id if defined
+ */
+ u32 id;
};
/**
@@ -250,6 +255,9 @@ struct w1_master
int enable_pullup;
/** 5V strong pullup duration in milliseconds, zero disabled. */
int pullup_duration;
+
+ int shortcircuit;
+ int presence;
long flags;
diff --git a/drivers/w1/w1_int.c b/drivers/w1/w1_int.c
index a4b4a8d..fc642b8 100644
--- a/drivers/w1/w1_int.c
+++ b/drivers/w1/w1_int.c
@@ -40,7 +40,7 @@ module_param_named(enable_pullup, w1_enable_pullup, int, 0);
static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
struct device_driver *driver,
- struct device *device)
+ struct device *device, u32 name_id)
{
struct w1_master *dev;
int err;
@@ -80,8 +80,9 @@ static struct w1_master *w1_alloc_dev(u32 id, int slave_count, int slave_ttl,
mutex_init(&dev->list_mutex);
memcpy(&dev->dev, device, sizeof(struct device));
- dev_set_name(&dev->dev, "w1_bus_master%u", dev->id);
- snprintf(dev->name, sizeof(dev->name), "w1_bus_master%u", dev->id);
+ // assign bus-id by gpio id
+ dev_set_name(&dev->dev, "w1_bus_master%u", name_id);
+ snprintf(dev->name, sizeof(dev->name), "w1_bus_master%u", name_id);
dev->dev.init_name = dev->name;
dev->driver = driver;
@@ -152,8 +153,10 @@ int w1_add_master_device(struct w1_bus_master *master)
}
} while (found);
+ if( (int) master->id <= 0)
+ master->id = id;
dev = w1_alloc_dev(id, w1_max_slave_count, w1_max_slave_ttl,
- &w1_master_driver, &w1_master_device);
+ &w1_master_driver, &w1_master_device, master->id);
if (!dev) {
mutex_unlock(&w1_mlock);
return -ENOMEM;
diff --git a/drivers/w1/w1_io.c b/drivers/w1/w1_io.c
index fd0550f..4d89b3d 100644
--- a/drivers/w1/w1_io.c
+++ b/drivers/w1/w1_io.c
@@ -370,6 +370,10 @@ int w1_reset_bus(struct w1_master *dev)
*/
/* w1_delay(430); min required time */
msleep(1);
+
+ /* detect short ciruit */
+ if( !(dev->bus_master->read_bit(dev->bus_master->data) & 0x1))
+ result = 2;
}
if(w1_disable_irqs) local_irq_restore(flags);
We aren't accepting any more changes to the board support code (bcm2708.c and bcm2709.c) - RPi releases will be switching to 4.4 in a matter of days, and the code you have modified no longer exists. All platform devices must now be instantiated using Device Tree, and non-DT operation is no longer supported.
The w1-gpio changes are not Pi-specific and should go upstream. Reading that thread you linked to it sounds as though Markus Pargmann would have started upstreaming the crash fix in April last year if you had replied to him.
That 10-channel overlay is an inelegant solution because it always tries to create all 10 channels, with 10 unique GPIOs, regardless of whether the user wants that many. I have a relatively simple change in the pipeline that allows fragments to be conditionally enabled and disabled. A further change to allow parametric node names (load a single-channel overlay 10 times) needs more work.
@phmarek has your issue been resolved? If so, please close this issue. Thanks.
There is a dtoverlay tweak where you can specify multiple 1-wire overlay instances. https://www.raspberrypi.org/forums/viewtopic.php?f=107&t=156734
I've got two DS18B20 in the immediate vicinity of my RPi, so querying them via GPIO works fine.
Now I'd like to add some more; I'm afraid that the length of cables required (star, not bus) won't work anymore, so I'd like to ask about the state of multiple w1 buses on multiple GPIO pins.
ISTR that there have been patches floating around for that already; could that be picked too, please?