Hello all,
This is an attempt to add MikroBUS addon support using the approach
described by Grove connector patch series [0].
The patch series tests out 2 addon boards + pwm and GPIO on the MikroBUS
connector. The boards used are GPS3 Click (for UART) [1] and Weather
Click (for I2C) [2]. Additionally, I have tested relative GPIO numbering
using devicetree nexus nodes [3].
The patch series does not attempt to do any dynamic discovery for 1-wire
eeprom MikroBUS addon boards, nor does it provide any sysfs entry for
board addition/removal. The connector driver might include them after
the basic support is ironed out, but the existing patches for dynamic
overlays work fine.
The patch series has been tested on BeaglePlay [4].
I will now go over individual parts of the patch series, but for a
better picture of the approach, it would be best to checkout [0] first.
MikroBUS connector driver
-------------------------
Just a stub platform driver for now. Will be extended in the future for
dynamic board discovery using 1-wire eeprom present in some MikroBUS
addon boards.
While it is a stub driver, disabling it will make the GPIO connector
nexus node unreachable (any driver attempting to use it will enter
differed probing). So it is required.
MikroBUS connector Devicetree
------------------------------
The connector devicetree defines the MikroBUS GPIO nexus node. This
allows using pin numbering relative to MikroBUS connector pins in the
addon boards overlay. Currently, the patch uses a clockwise numbering:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
Additionally, in case PWM pin is not using channel 0, a nexus node for pwm
should also be used and go in the connector devicetree.
MikroBUS connector symbols overlay
----------------------------------
To make an overlay generic we need a standard name scheme which we
use across base boards. For the connector pins the pinmux phandle
shall be:
<connector-name>_<pin-name>_mux_<pin-function>
For the parent provider phandle, we use a similar naming scheme:
<connector-name>_<pin-name>_<pin-function>
For GPIO controller, I am using `MIKROBUS_GPIO` name since with nexus
nodes, we do not need to define individual pin gpio controllers.
The string symbols can be replaced with phandles once [5] is accepted.
That will make connector stacking much simpler.
MikroBUS addon board overlay
----------------------------
The patch puts the addon board overlays in their own directory. I am
using the following naming scheme for MikroBUS addon boards:
<vendor>-<product_id>.dtso
Mikroe [6] lists this for all boards in their website, but I am not sure
if other vendors have a product_id.
This naming also makes future dynamic discovery easier, since click id
spec [7] contains vendor_id and product_id in the header.
Usage
-----
So what does this all look like? Let's take an example of a BeaglePlay
with one MikroBUS connectors for which we have physically attached a
Wather click module to the first connector. Doing ahead of time
command-line DT overlay application:
./fdtoverlay \
-o output.dtb \
-i k3-am625-beagleplay.dtb \
k3-am625-beagleplay-mikrobus-connector0.dtbo mikroe-5761.dtbo
Open Items
----------
- SPI Support:
Currently SPI dt requires `reg` property to specify the
chipselect to use. This, makes the SPI device overlay dependent on the
SPI controller. Thus for SPI support, we need a way to allow defining
SPI chipselect relative to MikroBUS pins, and not the actual device
controller.
One possible solution is to introduce something like `named-reg` and
allow selecting the chipselect by string array. But this probably
requires more discussion so I have left out SPI support for now.
NOTE: pins other than the CS MikroBUS pin can be used as chipselect.
See [8].
- Controller symbol duplication
The current symbol scheme has multiple symbols for the same underlying
controller (Eg: MIKROBUS_SCL_MUX_I2C_SCL and MIKROBUS_SDA_MUX_I2C_SDA)
point to the same i2c controller.
I think both of them will always use the same i2c controller, but
maybe there are some exceptions? So I have left it as it is for this
patch series. The same thing also applies to UART and SPI.
NOTE: with the use of nexus node for GPIO, the GPIO controller symbol
will be the same for all pins.
- Nexus node dt-bindings
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
[0]: https://lore.kernel.org/linux-arm-kernel/20240702164403.29067-1-afd@ti.com/
[1]: https://www.mikroe.com/gps-3-click
[2]: https://www.mikroe.com/weather-click
[3]: https://devicetree-specification.readthedocs.io/en/v0.3/devicetree-basics.html#nexus-nodes-and-specifier-mapping
[4]: https://www.beagleboard.org/boards/beagleplay
[5]: https://lore.kernel.org/r/20240902-symbol-phandle-v1-0-683efb2a944b@beagleboard.org
[6]: https://www.mikroe.com/
[7]: https://github.com/MikroElektronika/click_id
[8]: https://www.mikroe.com/spi-extend-click
Signed-off-by: Ayush Singh <redacted>
---
Ayush Singh (7):
dt-bindings: connector: Add MikorBUS connector
mikrobus: Add mikrobus driver
dts: ti: k3-am625-beagleplay: Enable mikroBUS connector
dts: ti: beagleplay: Add mikrobus connector symbols
addon_boards: Add addon_boards plumbing
addon_boards: mikrobus: Add Weather Click
addon_boards: mikrobus: Add GPS3 Click
Fabien Parent (1):
rust: kernel: Add Platform device and driver abstractions
.../bindings/connector/mikrobus-connector.yaml | 40 +++
Kbuild | 1 +
Kconfig | 2 +
MAINTAINERS | 8 +
addon_boards/Kconfig | 16 +
addon_boards/Makefile | 3 +
addon_boards/mikrobus/Makefile | 4 +
addon_boards/mikrobus/mikroe-1714.dtso | 28 ++
addon_boards/mikrobus/mikroe-5761-i2c.dtso | 28 ++
arch/arm64/boot/dts/ti/Makefile | 1 +
.../k3-am625-beagleplay-mikrobus-connector0.dtso | 49 +++
arch/arm64/boot/dts/ti/k3-am625-beagleplay.dts | 53 ++-
drivers/misc/Kconfig | 17 +
drivers/misc/Makefile | 1 +
drivers/misc/mikrobus.rs | 32 ++
rust/bindings/bindings_helper.h | 1 +
rust/kernel/lib.rs | 1 +
rust/kernel/platform.rs | 380 +++++++++++++++++++++
18 files changed, 659 insertions(+), 6 deletions(-)
---
base-commit: 9aaeb87ce1e966169a57f53a02ba05b30880ffb8
change-id: 20240826-mikrobus-dt-52eaaadd0b1f
Best regards,
--
Ayush Singh [off-list ref]
From: Fabien Parent <redacted>
Ports Platform device and driver abstractions from Fabien's tree [0].
These abstractions do not depend on any generic driver registration and
id table. Instead, the minimal abstractions have been implemented
specifically for platform subsystem taking heavy inspiration from the
existing phy device and driver abstractions.
[0]: https://github.com/Fabo/linux/commits/fparent/rust-platform
Signed-off-by: Fabien Parent <redacted>
Signed-off-by: Ayush Singh <redacted>
---
rust/bindings/bindings_helper.h | 1 +
rust/kernel/lib.rs | 1 +
rust/kernel/platform.rs | 380 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 382 insertions(+)
@@ -0,0 +1,380 @@+// SPDX-License-Identifier: GPL-2.0++//! Platform devices and drivers.+//!+//! Also called `platformdev`, `pdev`.+//!+//! C header: [`include/linux/platform_device.h`](../../../../include/linux/platform_device.h)++usecore::{marker::PhantomData,pin::Pin,ptr::addr_of_mut};++usemacros::vtable;++usecrate::{+bindings,device,+error::{from_result,Result},+str::CStr,+types::Opaque,+};++/// A platform device.+///+/// # Invariants+///+/// The field `ptr` is non-null and valid for the lifetime of the object.+#[repr(transparent)]+pubstructDevice(Opaque<bindings::platform_device>);++implDevice{+/// Creates a new [`Device`] instance from a raw pointer.+///+/// # Safety+///+/// For the duration of `'a`,+/// - the pointer must point at a valid `platform_device`, and the caller+/// must be in a context where all methods defined on this struct+/// are safe to call.+unsafefnfrom_raw<'a>(ptr:*mutbindings::platform_device)->&'amutSelf{+// CAST: `Self` is a `repr(transparent)` wrapper around `bindings::platform_device`.+letptr=ptr.cast::<Self>();+// SAFETY: by the function requirements the pointer is valid and we have unique access for+// the duration of `'a`.+unsafe{&mut*ptr}+}++/// Returns id of the platform device.+pubfnid(&self)->i32{+letplatformdev=self.0.get();+// SAFETY: By the type invariants, we know that `self.ptr` is non-null and valid.+unsafe{(*platformdev).id}+}+}++implAsRef<device::Device>forDevice{+fnas_ref(&self)->&device::Device{+letplatformdev=self.0.get();+// SAFETY: By the type invariants, we know that `self.ptr` is non-null and valid.+unsafe{device::Device::as_ref(addr_of_mut!((*platformdev).dev))}+}+}++/// An adapter for the registration of a Platform driver.+structAdapter<T:Driver>{+_p:PhantomData<T>,+}++impl<T:Driver>Adapter<T>{+/// # Safety+///+/// `pdev` must be passed by the corresponding callback in `platform_driver`.+unsafeextern"C"fnprobe_callback(pdev:*mutbindings::platform_device)->core::ffi::c_int{+from_result(||{+// SAFETY: This callback is called only in contexts+// where we can exclusively access `platform_device` because+// it's not published yet, so the accessors on `Device` are okay+// to call.+letdev=unsafe{Device::from_raw(pdev)};+T::probe(dev)?;+Ok(0)+})+}++/// # Safety+///+/// `pdev` must be passed by the corresponding callback in `platform_driver`.+unsafeextern"C"fnremove_callback(pdev:*mutbindings::platform_device){+// SAFETY: This callback is called only in contexts+// where we can exclusively access `platform_device` because+// it's not published yet, so the accessors on `Device` are okay+// to call.+letdev=unsafe{Device::from_raw(pdev)};+T::remove(dev);+}+}++/// Driver structure for a particular Platform driver.+///+/// Wraps the kernel's [`struct platform_driver`].+/// This is used to register a driver for a particular PHY type with the kernel.+///+/// # Invariants+///+/// `self.0` is always in a valid state.+///+/// [`struct platform_driver`]: srctree/include/linux/platform.h+#[repr(transparent)]+pubstructDriverVTable(Opaque<bindings::platform_driver>);++// SAFETY: `DriverVTable` doesn't expose any &self method to access internal data, so it's safe to+// share `&DriverVTable` across execution context boundaries.+unsafeimplSyncforDriverVTable{}++implDriverVTable{+/// Creates a [`DriverVTable`] instance from [`Driver`].+///+/// This is used by [`module_platform_driver`] macro to create a static array of `phy_driver`.+///+/// [`module_platform_driver`]: crate::module_platform_driver+pubconstfnnew<T:Driver,constC:usize>(match_tbl:&'staticDeviceIdTable<C>)->Self{+letdrv=Opaque::new(bindings::platform_driver{+probe:ifT::HAS_PROBE{+Some(Adapter::<T>::probe_callback)+}else{+None+},+__bindgen_anon_1:bindings::platform_driver__bindgen_ty_1{+remove:ifT::HAS_REMOVE{+Some(Adapter::<T>::remove_callback)+}else{+None+},+},+driver:create_device_driver::<T,C>(match_tbl),+// SAFETY: The rest is zeroed out to initialize `struct platform_driver`.+..unsafe{core::mem::MaybeUninit::<bindings::platform_driver>::zeroed().assume_init()}+});++DriverVTable(drv)+}+}++constfncreate_device_driver<T:Driver,constC:usize>(+match_tbl:&'staticDeviceIdTable<C>,+)->bindings::device_driver{+bindings::device_driver{+name:T::NAME.as_char_ptr(),+of_match_table:match_tbl.get(),+// SAFETY: The rest is zeroed out to initialize `struct device_driver`.+..unsafe{core::mem::MaybeUninit::<bindings::device_driver>::zeroed().assume_init()}+}+}++/// A platform driver.+#[vtable]+pubtraitDriver{+/// The friendly name+constNAME:&'staticCStr;++/// Sets up device-specific structures during discovery.+fnprobe(_dev:&mutDevice)->Result;++/// Clean up device-specific structures during removal.+fnremove(_dev:&mutDevice);+}++/// Registration structure for Platform driver.+///+/// Registers [`DriverVTable`] instance with the kernel. It will be unregistered when dropped.+///+/// # Invariants+///+/// The `driver` is currently registered to the kernel via `__platform_driver_register`.+pubstructRegistration(Pin<&'staticDriverVTable>);++// SAFETY: The only action allowed in a `Registration` instance is dropping it, which is safe to do+// from any thread because `platform_drivers_unregister` can be called from any thread context.+unsafeimplSendforRegistration{}++implRegistration{+/// Registers a Platform driver.+pubfnnew(drv:Pin<&'staticDriverVTable>,m:&'staticcrate::ThisModule)->Registration{+unsafe{+bindings::__platform_driver_register(drv.0.get(),m.0);+}++Self(drv)+}+}++implDropforRegistration{+fndrop(&mutself){+unsafe{bindings::platform_driver_unregister(self.0.0.get())}+}+}++/// An identifier for Platform devices.+///+/// Represents the kernel's [`struct of_device_id`]. This is used to find an appropriate+/// Platform driver.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pubstructDeviceId(&'staticCStr);++implDeviceId{+/// A zeroed [`struct of_device_id`] used to signify end of of_device_id array.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pubconstZERO:bindings::of_device_id=bindings::of_device_id{+// SAFETY: The rest is zeroed out to initialize `struct of_device_id`.+..unsafe{core::mem::MaybeUninit::<bindings::of_device_id>::zeroed().assume_init()}+};++/// Create new instance+pubconstfnnew(s:&'staticCStr)->Self{+Self(s)+}++constfncompatible(&self)->[i8;128]{+letcompatible=self.0.as_bytes_with_nul();+letmutcomp=[0i8;128];+letmuti=0;++whilei<compatible.len(){+comp[i]=compatible[i]as_;+i+=1;+}++comp+}++// macro use only+#[doc(hidden)]+pubconstfnto_rawid(&self)->bindings::of_device_id{+letcomp=self.compatible();++bindings::of_device_id{+compatible:comp,+// SAFETY: The rest is zeroed out to initialize `struct of_device_id`.+..unsafe{core::mem::MaybeUninit::<bindings::of_device_id>::zeroed().assume_init()}+}+}+}++/// An array of identifiers for platform driver+#[repr(transparent)]+pubstructDeviceIdTable<constC:usize>([bindings::of_device_id;C]);++impl<constC:usize>DeviceIdTable<C>{+/// Create a new instance+pubconstfnnew(ids:[bindings::of_device_id;C])->Self{+Self(ids)+}++/// Returns a raw pointer to static table.+pubconstfnget(&'staticself)->*constbindings::of_device_id{+self.0.as_ptr()+}+}++// SAFETY: `DeviceIdTable` is only used in C side behind a *const pointer, and thus remains+// immutable and thus can be shared across execution context boundaries.+unsafeimpl<constC:usize>SyncforDeviceIdTable<C>{}++/// Declares a kernel module for Platform drivers.+///+/// This creates a static [`struct platform_driver`] and registers it. It also creates an array of+/// [`struct of_device_id`] for matching the driver to devicetree device.+///+/// [`struct platform_driver`]: srctree/include/linux/platform.h+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+///+/// # Examples+///+/// ```+/// # mod module_platform_driver_sample {+/// use kernel::c_str;+/// use kernel::platform::{self, DeviceId};+/// use kernel::prelude::*;+///+/// kernel::module_platform_driver! {+/// driver: PlatformSimple,+/// of_table: [DeviceId::new(c_str!("platform-simple"))],+/// name: "rust_sample_platform",+/// author: "Rust for Linux Contributors",+/// description: "Rust sample Platform driver",+/// license: "GPL",+/// }+///+/// struct PlatformSimple;+///+/// #[vtable]+/// impl platform::Driver for PlatformSimple {+/// const NAME: &'static CStr = c_str!("PlatformSimple");+/// }+/// # }+/// ```+///+/// This expands to the following code:+///+/// ```ignore+/// use kernel::c_str;+/// use kernel::platform::{self, DeviceId};+/// use kernel::prelude::*;+///+///+/// struct Module {+/// _reg: $crate::platform::Registration,+/// }+///+/// module! {+/// type: Module,+/// name: "rust_sample_platform",+/// author: "Rust for Linux Contributors",+/// description: "Rust sample Platform driver",+/// license: "GPL",+/// }+///+/// const _: () = {+/// static OF_TABLE: $crate::platform::DeviceIdTable = $crate::platform::DeviceIdTable<2>([+/// (DeviceId::new(c_str!("platform-simple"))).to_rawid(),+/// $crate::platform::DeviceId::ZERO,+/// ]);+/// static DRIVER: $crate::platform::DriverVTable =+/// $crate::platform::DriverVTable::new::<MikrobusDriver, 2>(&OF_TABLE);+/// impl $crate::Module for Module {+/// fn init(module: &'static ThisModule) -> Result<Self> {+/// let reg =+/// $crate::platform::Registration::new(+/// ::core::pin::Pin::static_ref(&DRIVER), module);+/// Ok(Module { _reg: reg })+/// }+/// }+/// }+///+/// struct PlatformSimple;+///+/// #[vtable]+/// impl platform::Driver for PlatformSimple {+/// const NAME: &'static CStr = c_str!("PlatformSimple");+/// }+/// ```+#[macro_export]+macro_rules!module_platform_driver{+(@replace_expr$_t:tt$sub:expr)=>{$sub};++(@count_devices$($x:expr),*)=>{+0usize$(+$crate::module_platform_driver!(@replace_expr$x1usize))*+};++(driver:$driver:ident,of_table:[$($of_id:expr),+$(,)?],$($f:tt)*)=>{+structModule{+_reg:$crate::platform::Registration,+}++$crate::prelude::module!{+type:Module,+$($f)*+}++const_:()={+// SAFETY: C will not read off the end of this constant since the last element is zero.+staticOF_TABLE:$crate::platform::DeviceIdTable<+{$crate::module_platform_driver!(@count_devices$($of_id),+)+1}>=+$crate::platform::DeviceIdTable::new(+[$($of_id.to_rawid()),*,$crate::platform::DeviceId::ZERO]);++staticDRIVER:$crate::platform::DriverVTable=+$crate::platform::DriverVTable::new::<+$driver,{$crate::module_platform_driver!(@count_devices$($of_id),+)+1}+>(&OF_TABLE);++impl$crate::ModuleforModule{+fninit(module:&'staticThisModule)->Result<Self>{+letreg=$crate::platform::Registration::new(+::core::pin::Pin::static_ref(&DRIVER),module);+Ok(Module{_reg:reg})+}+}+};+};+}
Add DT bindings for mikroBUS interface. MikroBUS [0] is an open standard
developed by MikroElektronika for connecting add-on boards to
microcontrollers or microprocessors.
MikroBUS connector node will optionally act as nexus nodes for routing
GPIOs and PWM.
For GPIOs, the following pin numbering should be followed:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
For PWM, the PWM pin should be on channel 0.
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
[0]: https://www.mikroe.com/
Signed-off-by: Ayush Singh <redacted>
---
.../bindings/connector/mikrobus-connector.yaml | 40 ++++++++++++++++++++++
MAINTAINERS | 5 +++
2 files changed, 45 insertions(+)
A simple platform driver for now that does nothing. This is required
because without a platform driver, the mikrobus_gpio0 nexus node cannot
be used.
In future, this driver will also allow for dynamic board detection using
1-wire eeprom in new mikrobus boards.
Signed-off-by: Ayush Singh <redacted>
---
MAINTAINERS | 1 +
drivers/misc/Kconfig | 17 +++++++++++++++++
drivers/misc/Makefile | 1 +
drivers/misc/mikrobus.rs | 32 ++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+)
A directory to store and build addon_board overlays like mikroBUS,
Groove, etc. The overlays present here should be completely independent
of the underlying connector.
Signed-off-by: Ayush Singh <redacted>
---
Kbuild | 1 +
Kconfig | 2 ++
MAINTAINERS | 1 +
addon_boards/Kconfig | 16 ++++++++++++++++
addon_boards/Makefile | 3 +++
addon_boards/mikrobus/Makefile | 1 +
6 files changed, 24 insertions(+)
On Wed, Sep 11, 2024 at 07:57:18PM +0530, Ayush Singh wrote:
quoted hunk
+/// An identifier for Platform devices.+///+/// Represents the kernel's [`struct of_device_id`]. This is used to find an appropriate+/// Platform driver.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pub struct DeviceId(&'static CStr);++impl DeviceId {
<snip>
I appreciate posting this, but this really should go on top of the
device driver work Danilo Krummrich has been doing. He and I spent a
lot of time working through this this past weekend (well, him talking
and explaining, and me asking too many stupid questions...)
I think what he has will make the platform driver/device work simpler
here, and I'll be glad to take it based on that, this "independent" code
that doesn't interact with that isn't the best idea overall.
It also will properly handle the "Driver" interaction as well, which we
need to get right, not a one-off like this for a platform driver.
Hopefully that will not cause much, if any, changes for your use of this
in your driver, but let's see.
thanks,
greg k-h
On Wed, Sep 11, 2024 at 07:57:20PM +0530, Ayush Singh wrote:
quoted hunk
A simple platform driver for now that does nothing. This is required
because without a platform driver, the mikrobus_gpio0 nexus node cannot
be used.
In future, this driver will also allow for dynamic board detection using
1-wire eeprom in new mikrobus boards.
Signed-off-by: Ayush Singh <redacted>
---
MAINTAINERS | 1 +
drivers/misc/Kconfig | 17 +++++++++++++++++
drivers/misc/Makefile | 1 +
drivers/misc/mikrobus.rs | 32 ++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+)
@@ -610,6 +610,23 @@ config MARVELL_CN10K_DPITocompilethisdriverasamodule,chooseMhere:themodulewillbecalledmrvl_cn10k_dpi.+menuconfigMIKROBUS+tristate"Module for instantiating devices on mikroBUS ports"+help+ThisoptionenablesthemikroBUSdriver.mikroBUSisanadd-on+boardsocketstandardthatoffersmaximumexpandabilitywith+thesmallestnumberofpins.ThemikroBUSdriverinstantiates+devicesonamikroBUSportdescribedbyidentifyingdatapresent+inanadd-onboardresidentEEPROM,moredetailsonthemikroBUS+driversupportanddiscussioncanbefoundinthiseLinuxwiki:+elinux.org/Mikrobus
So you want to be a bus? Or just a single driver? I'm confused, what
exactly is this supposed to do?
If a bus, great, let's tie into the proper driver core bus code, don't
"open code" all of that, as that's just going to make things messier and
harder to work overall in the end.
If a single driver, why is it called "bus"? :)
thanks,
greg k-h
On Wed, Sep 11, 2024 at 07:57:23PM +0530, Ayush Singh wrote:
A directory to store and build addon_board overlays like mikroBUS,
Groove, etc. The overlays present here should be completely independent
of the underlying connector.
Signed-off-by: Ayush Singh <redacted>
---
Kbuild | 1 +
Kconfig | 2 ++
MAINTAINERS | 1 +
addon_boards/Kconfig | 16 ++++++++++++++++
addon_boards/Makefile | 3 +++
addon_boards/mikrobus/Makefile | 1 +
6 files changed, 24 insertions(+)
Ah, here's where you add this.
It should be below drivers/ right? But what's wrong with drivers/soc/?
Why is this so special? Why not just under
drivers/microbus/addon_boards/ ? Why is this tiny bus/device so
different from everything else out there?
thanks,
greg k-h
On Wed, 11 Sep 2024 19:57:19 +0530, Ayush Singh wrote:
Add DT bindings for mikroBUS interface. MikroBUS [0] is an open standard
developed by MikroElektronika for connecting add-on boards to
microcontrollers or microprocessors.
MikroBUS connector node will optionally act as nexus nodes for routing
GPIOs and PWM.
For GPIOs, the following pin numbering should be followed:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
For PWM, the PWM pin should be on channel 0.
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
[0]: https://www.mikroe.com/
Signed-off-by: Ayush Singh <redacted>
---
.../bindings/connector/mikrobus-connector.yaml | 40 ++++++++++++++++++++++
MAINTAINERS | 5 +++
2 files changed, 45 insertions(+)
My bot found errors running 'make dt_binding_check' on your patch:
yamllint warnings/errors:
dtschema/dtc warnings/errors:
/builds/robherring/dt-review-ci/linux/Documentation/devicetree/bindings/connector/mikrobus-connector.example.dtb: mikrobus-connector0: 'gpio-controller' is a dependency of '#gpio-cells'
from schema $id: http://devicetree.org/schemas/gpio/gpio.yaml#
doc reference errors (make refcheckdocs):
See https://patchwork.ozlabs.org/project/devicetree-bindings/patch/20240911-mikrobus-dt-v1-2-3ded4dc879e7@beagleboard.org
The base for the series is generally the latest rc1. A different dependency
should be noted in *this* patch.
If you already ran 'make dt_binding_check' and didn't see the above
error(s), then make sure 'yamllint' is installed and dt-schema is up to
date:
pip3 install dtschema --upgrade
Please check and re-submit after running the above command yourself. Note
that DT_SCHEMA_FILES can be set to your schema file to speed up checking
your schema. However, it must be unset to test all examples with your schema.
On Wed, Sep 11, 2024 at 07:57:18PM +0530, Ayush Singh wrote:
quoted
+/// An identifier for Platform devices.+///+/// Represents the kernel's [`struct of_device_id`]. This is used to find an appropriate+/// Platform driver.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pub struct DeviceId(&'static CStr);++impl DeviceId {
<snip>
I appreciate posting this, but this really should go on top of the
device driver work Danilo Krummrich has been doing. He and I spent a
lot of time working through this this past weekend (well, him talking
and explaining, and me asking too many stupid questions...)
I think what he has will make the platform driver/device work simpler
here, and I'll be glad to take it based on that, this "independent" code
that doesn't interact with that isn't the best idea overall.
It also will properly handle the "Driver" interaction as well, which we
need to get right, not a one-off like this for a platform driver.
Hopefully that will not cause much, if any, changes for your use of this
in your driver, but let's see.
thanks,
greg k-h
Sure, can you provide me a link to patches or maybe the branch containing that work? I also think it would be good to have the link in Zulip discussion for Platform Device and Driver.
Ayush Singh
Odd top-level directory for the kernel, are you sure this is correct?
thanks,
greg k-h
Well, it is kinda a temporary location, since well, I could not find a good place for board overlays but a top-level location seems better than putting them in any arch specific location. I am open to moving them to a more suitable location if we have one.
Ayush Singh
On Wed, Sep 11, 2024 at 07:57:20PM +0530, Ayush Singh wrote:
quoted
A simple platform driver for now that does nothing. This is required
because without a platform driver, the mikrobus_gpio0 nexus node cannot
be used.
In future, this driver will also allow for dynamic board detection using
1-wire eeprom in new mikrobus boards.
Signed-off-by: Ayush Singh <redacted>
---
MAINTAINERS | 1 +
drivers/misc/Kconfig | 17 +++++++++++++++++
drivers/misc/Makefile | 1 +
drivers/misc/mikrobus.rs | 32 ++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+)
@@ -610,6 +610,23 @@ config MARVELL_CN10K_DPITocompilethisdriverasamodule,chooseMhere:themodulewillbecalledmrvl_cn10k_dpi.+menuconfigMIKROBUS+tristate"Module for instantiating devices on mikroBUS ports"+help+ThisoptionenablesthemikroBUSdriver.mikroBUSisanadd-on+boardsocketstandardthatoffersmaximumexpandabilitywith+thesmallestnumberofpins.ThemikroBUSdriverinstantiates+devicesonamikroBUSportdescribedbyidentifyingdatapresent+inanadd-onboardresidentEEPROM,moredetailsonthemikroBUS+driversupportanddiscussioncanbefoundinthiseLinuxwiki:+elinux.org/Mikrobus
So you want to be a bus? Or just a single driver? I'm confused, what
exactly is this supposed to do?
If a bus, great, let's tie into the proper driver core bus code, don't
"open code" all of that, as that's just going to make things messier and
harder to work overall in the end.
If a single driver, why is it called "bus"? :)
thanks,
greg k-h
Well, mikroBUS [0] is the name of the socket standard. It is basically a group of following pins:
Analog - AN
Reset - RST
SPI Chip Select - CS
SPI Clock - SCK
SPI Master Input Slave Output - MISO
SPI Master Output Slave Input - MOSI
VCC-3.3V power - +3.3V
Reference Ground - GND
PWM - PWM output
INT - Hardware Interrupt
RX - UART Receive
TX - UART Transmit
SCL - I2C Clock
SDA - I2C Data
+5V - VCC-5V power
GND - Reference Ground
I do not think it would qualify as as a "bus" in the Linux driver sense. Especially with the devicetree based approach here which applies overlay directly to the actual uart/i2c/spi controllers and basically not interact with the mikroBUS node much.
The driver is here to enable the following:
1. Enable dynamic board detection using 1-wire eeprom on some addon boards.
2. Provide sysfs entry for runtime board adding/removal
3. Enable using mikrobus connector node as nexus node for GPIO (not having a platform driver makes any driver trying to use the connector as nexus node go into deffered probing state).
For this patch series, the driver is mostly here due to point 3. Basically a stub.
[0]: https://www.mikroe.com/mikrobus
Ayush Singh
On Wed, Sep 11, 2024 at 07:57:23PM +0530, Ayush Singh wrote:
quoted
A directory to store and build addon_board overlays like mikroBUS,
Groove, etc. The overlays present here should be completely independent
of the underlying connector.
Signed-off-by: Ayush Singh <redacted>
---
Kbuild | 1 +
Kconfig | 2 ++
MAINTAINERS | 1 +
addon_boards/Kconfig | 16 ++++++++++++++++
addon_boards/Makefile | 3 +++
addon_boards/mikrobus/Makefile | 1 +
6 files changed, 24 insertions(+)
Ah, here's where you add this.
It should be below drivers/ right? But what's wrong with drivers/soc/?
Why is this so special? Why not just under
drivers/microbus/addon_boards/ ? Why is this tiny bus/device so
different from everything else out there?
thanks,
greg k-h
From: Rob Herring <robh@kernel.org> Date: 2024-09-11 17:02:46
On Wed, Sep 11, 2024 at 07:57:17PM +0530, Ayush Singh wrote:
Hello all,
This is an attempt to add MikroBUS addon support using the approach
described by Grove connector patch series [0].
The patch series tests out 2 addon boards + pwm and GPIO on the MikroBUS
connector. The boards used are GPS3 Click (for UART) [1] and Weather
Click (for I2C) [2]. Additionally, I have tested relative GPIO numbering
using devicetree nexus nodes [3].
The patch series does not attempt to do any dynamic discovery for 1-wire
eeprom MikroBUS addon boards, nor does it provide any sysfs entry for
board addition/removal. The connector driver might include them after
the basic support is ironed out, but the existing patches for dynamic
overlays work fine.
The patch series has been tested on BeaglePlay [4].
I will now go over individual parts of the patch series, but for a
better picture of the approach, it would be best to checkout [0] first.
MikroBUS connector driver
-------------------------
Just a stub platform driver for now. Will be extended in the future for
dynamic board discovery using 1-wire eeprom present in some MikroBUS
addon boards.
While it is a stub driver, disabling it will make the GPIO connector
nexus node unreachable (any driver attempting to use it will enter
differed probing). So it is required.
MikroBUS connector Devicetree
------------------------------
The connector devicetree defines the MikroBUS GPIO nexus node. This
allows using pin numbering relative to MikroBUS connector pins in the
addon boards overlay. Currently, the patch uses a clockwise numbering:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
Additionally, in case PWM pin is not using channel 0, a nexus node for pwm
should also be used and go in the connector devicetree.
MikroBUS connector symbols overlay
----------------------------------
To make an overlay generic we need a standard name scheme which we
use across base boards. For the connector pins the pinmux phandle
shall be:
<connector-name>_<pin-name>_mux_<pin-function>
For the parent provider phandle, we use a similar naming scheme:
<connector-name>_<pin-name>_<pin-function>
For GPIO controller, I am using `MIKROBUS_GPIO` name since with nexus
nodes, we do not need to define individual pin gpio controllers.
The string symbols can be replaced with phandles once [5] is accepted.
That will make connector stacking much simpler.
MikroBUS addon board overlay
----------------------------
The patch puts the addon board overlays in their own directory. I am
using the following naming scheme for MikroBUS addon boards:
<vendor>-<product_id>.dtso
Mikroe [6] lists this for all boards in their website, but I am not sure
if other vendors have a product_id.
This naming also makes future dynamic discovery easier, since click id
spec [7] contains vendor_id and product_id in the header.
Usage
-----
So what does this all look like? Let's take an example of a BeaglePlay
with one MikroBUS connectors for which we have physically attached a
Wather click module to the first connector. Doing ahead of time
command-line DT overlay application:
./fdtoverlay \
-o output.dtb \
-i k3-am625-beagleplay.dtb \
k3-am625-beagleplay-mikrobus-connector0.dtbo mikroe-5761.dtbo
Open Items
----------
- SPI Support:
Currently SPI dt requires `reg` property to specify the
chipselect to use. This, makes the SPI device overlay dependent on the
SPI controller. Thus for SPI support, we need a way to allow defining
SPI chipselect relative to MikroBUS pins, and not the actual device
controller.
One possible solution is to introduce something like `named-reg` and
allow selecting the chipselect by string array. But this probably
requires more discussion so I have left out SPI support for now.
NOTE: pins other than the CS MikroBUS pin can be used as chipselect.
See [8].
- Controller symbol duplication
The current symbol scheme has multiple symbols for the same underlying
controller (Eg: MIKROBUS_SCL_MUX_I2C_SCL and MIKROBUS_SDA_MUX_I2C_SDA)
point to the same i2c controller.
I think both of them will always use the same i2c controller, but
maybe there are some exceptions? So I have left it as it is for this
patch series. The same thing also applies to UART and SPI.
NOTE: with the use of nexus node for GPIO, the GPIO controller symbol
will be the same for all pins.
- Nexus node dt-bindings
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
Please submit a fix to dtschema. Either GH PR or patch to
devicetree-spec list.
Rob
From: Rob Herring <robh@kernel.org> Date: 2024-09-11 17:26:27
On Wed, Sep 11, 2024 at 07:57:19PM +0530, Ayush Singh wrote:
Add DT bindings for mikroBUS interface. MikroBUS [0] is an open standard
developed by MikroElektronika for connecting add-on boards to
microcontrollers or microprocessors.
Typo in the subject...
Isn't this v6? Where's the revision history?
quoted hunk
MikroBUS connector node will optionally act as nexus nodes for routing
GPIOs and PWM.
For GPIOs, the following pin numbering should be followed:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
For PWM, the PWM pin should be on channel 0.
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
[0]: https://www.mikroe.com/
Signed-off-by: Ayush Singh <redacted>
---
.../bindings/connector/mikrobus-connector.yaml | 40 ++++++++++++++++++++++
MAINTAINERS | 5 +++
2 files changed, 45 insertions(+)
On Wed, Sep 11, 2024 at 04:56:14PM +0200, Greg Kroah-Hartman wrote:
On Wed, Sep 11, 2024 at 07:57:18PM +0530, Ayush Singh wrote:
quoted
+/// An identifier for Platform devices.+///+/// Represents the kernel's [`struct of_device_id`]. This is used to find an appropriate+/// Platform driver.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pub struct DeviceId(&'static CStr);++impl DeviceId {
<snip>
I appreciate posting this, but this really should go on top of the
device driver work Danilo Krummrich has been doing.
If everyone agrees, I'd offer to just provide platform device / driver
abstractions with my next patch series. This way you don't need to worry
about aligning things with the rest of the abstractions yourself and throughout
potential further versions of the series.
Just be aware that I probably won't get to work on it until after LPC.
He and I spent a
lot of time working through this this past weekend (well, him talking
and explaining, and me asking too many stupid questions...)
I think what he has will make the platform driver/device work simpler
here, and I'll be glad to take it based on that, this "independent" code
that doesn't interact with that isn't the best idea overall.
It also will properly handle the "Driver" interaction as well, which we
need to get right, not a one-off like this for a platform driver.
Hopefully that will not cause much, if any, changes for your use of this
in your driver, but let's see.
thanks,
greg k-h
Sure, can you provide me a link to patches or maybe the branch containing that work? I also think it would be good to have the link in Zulip discussion for Platform Device and Driver.
On Wed, Sep 11, 2024 at 07:57:19PM +0530, Ayush Singh wrote:
quoted
Add DT bindings for mikroBUS interface. MikroBUS [0] is an open standard
developed by MikroElektronika for connecting add-on boards to
microcontrollers or microprocessors.
Typo in the subject...
Isn't this v6? Where's the revision history?
Well, at this point, it almost has nothing in common with [0] (the previous patch series was about making mikroBUS a Linux bus) and is more of a continuation of [1]. So I thought it would be better to treat it as a new patch series.
quoted
MikroBUS connector node will optionally act as nexus nodes for routing
GPIOs and PWM.
For GPIOs, the following pin numbering should be followed:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
For PWM, the PWM pin should be on channel 0.
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
[0]: https://www.mikroe.com/
Signed-off-by: Ayush Singh <redacted>
---
.../bindings/connector/mikrobus-connector.yaml | 40 ++++++++++++++++++++++
MAINTAINERS | 5 +++
2 files changed, 45 insertions(+)
Sure, can you provide me a link to patches or maybe the branch containing that work? I also think it would be good to have the link in Zulip discussion for Platform Device and Driver.
On Wed, Sep 11, 2024 at 09:32:21PM +0530, Ayush Singh wrote:
On 9/11/24 20:27, Greg Kroah-Hartman wrote:
quoted
On Wed, Sep 11, 2024 at 07:57:20PM +0530, Ayush Singh wrote:
quoted
A simple platform driver for now that does nothing. This is required
because without a platform driver, the mikrobus_gpio0 nexus node cannot
be used.
In future, this driver will also allow for dynamic board detection using
1-wire eeprom in new mikrobus boards.
Signed-off-by: Ayush Singh <redacted>
---
MAINTAINERS | 1 +
drivers/misc/Kconfig | 17 +++++++++++++++++
drivers/misc/Makefile | 1 +
drivers/misc/mikrobus.rs | 32 ++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+)
@@ -610,6 +610,23 @@ config MARVELL_CN10K_DPITocompilethisdriverasamodule,chooseMhere:themodulewillbecalledmrvl_cn10k_dpi.+menuconfigMIKROBUS+tristate"Module for instantiating devices on mikroBUS ports"+help+ThisoptionenablesthemikroBUSdriver.mikroBUSisanadd-on+boardsocketstandardthatoffersmaximumexpandabilitywith+thesmallestnumberofpins.ThemikroBUSdriverinstantiates+devicesonamikroBUSportdescribedbyidentifyingdatapresent+inanadd-onboardresidentEEPROM,moredetailsonthemikroBUS+driversupportanddiscussioncanbefoundinthiseLinuxwiki:+elinux.org/Mikrobus
So you want to be a bus? Or just a single driver? I'm confused, what
exactly is this supposed to do?
If a bus, great, let's tie into the proper driver core bus code, don't
"open code" all of that, as that's just going to make things messier and
harder to work overall in the end.
If a single driver, why is it called "bus"? :)
thanks,
greg k-h
Well, mikroBUS [0] is the name of the socket standard. It is basically a
group of following pins:
Analog - AN
Reset - RST
SPI Chip Select - CS
SPI Clock - SCK
SPI Master Input Slave Output - MISO
SPI Master Output Slave Input - MOSI
VCC-3.3V power - +3.3V
Reference Ground - GND
PWM - PWM output
INT - Hardware Interrupt
RX - UART Receive
TX - UART Transmit
SCL - I2C Clock
SDA - I2C Data
+5V - VCC-5V power
GND - Reference Ground
I do not think it would qualify as as a "bus" in the Linux driver sense.
Especially with the devicetree based approach here which applies overlay
directly to the actual uart/i2c/spi controllers and basically not interact
with the mikroBUS node much.
It will be a "bus" in the driver sense as you want to have different
drivers bound to devices that are plugged in here, right? Or if this is
just a single driver for the hardware, then no, as you will not have any
additional drivers for this standard? It's unclear you want to do here.
The driver is here to enable the following:
1. Enable dynamic board detection using 1-wire eeprom on some addon boards.
Some, not all?
2. Provide sysfs entry for runtime board adding/removal
That's not what sysfs is for, but we can get there eventually...
3. Enable using mikrobus connector node as nexus node for GPIO (not having a
platform driver makes any driver trying to use the connector as nexus node
go into deffered probing state).
Why is this a platform device? Is this always going to be described by
DT somehow?
For this patch series, the driver is mostly here due to point 3. Basically a
stub.
Let's see how this really works before coming to conclusions.
As an example, how do you think sysfs should look for this device? For
all devices? Write out the needed sysfs documentation entries first and
then that will help explain things better.
thanks,
greg k-h
Odd top-level directory for the kernel, are you sure this is correct?
thanks,
greg k-h
Well, it is kinda a temporary location, since well, I could not find a good
place for board overlays but a top-level location seems better than putting
them in any arch specific location. I am open to moving them to a more
suitable location if we have one.
top-level location is not ok for something so tiny and "special". Just
put it where all other dtso files go.
thanks,
greg k-h
On Wed, Sep 11, 2024 at 07:35:35PM +0200, Danilo Krummrich wrote:
On Wed, Sep 11, 2024 at 04:56:14PM +0200, Greg Kroah-Hartman wrote:
quoted
On Wed, Sep 11, 2024 at 07:57:18PM +0530, Ayush Singh wrote:
quoted
+/// An identifier for Platform devices.+///+/// Represents the kernel's [`struct of_device_id`]. This is used to find an appropriate+/// Platform driver.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pub struct DeviceId(&'static CStr);++impl DeviceId {
<snip>
I appreciate posting this, but this really should go on top of the
device driver work Danilo Krummrich has been doing.
If everyone agrees, I'd offer to just provide platform device / driver
abstractions with my next patch series. This way you don't need to worry
about aligning things with the rest of the abstractions yourself and throughout
potential further versions of the series.
That sounds good to me, thanks!
Just be aware that I probably won't get to work on it until after LPC.
We will not be able to review anything until after LPC either :)
thanks,
greg k-h
On Wed, Sep 11, 2024 at 11:35:43PM +0530, Ayush Singh wrote:
On 9/11/24 23:09, Danilo Krummrich wrote:
quoted
On 9/11/24 5:52 PM, Ayush Singh wrote:
quoted
Sure, can you provide me a link to patches or maybe the branch
containing that work? I also think it would be good to have the link
in Zulip discussion for Platform Device and Driver.
Maybe the branch is just out of date? It still contains the generic
structures for IdArray, IdTable and RawDeviceId.
Has something changed since the discussion here [0]?
Yes, it has; this refers to what Greg mentioned when he said that we worked
through this last weekend in his original reply.
Things will probably not remain exactly this way, but the general concept of the
abstractions will, i.e. the existance of `IdArray`, `IdTable`, and some
`DeviceId` abstraction. Please also see [1].
[1] https://lore.kernel.org/rust-for-linux/ZuHU5yrJUOKnJGrB@pollux/
Odd top-level directory for the kernel, are you sure this is correct?
thanks,
greg k-h
Well, it is kinda a temporary location, since well, I could not find a good
place for board overlays but a top-level location seems better than putting
them in any arch specific location. I am open to moving them to a more
suitable location if we have one.
top-level location is not ok for something so tiny and "special". Just
put it where all other dtso files go.
thanks,
greg k-h
So here are the directories where dtso files currently go:
❯ find . -type f -name "*.dtso" -printf "%h\n" | sort -u
./arch/arm64/boot/dts/amlogic
./arch/arm64/boot/dts/freescale
./arch/arm64/boot/dts/mediatek
./arch/arm64/boot/dts/qcom
./arch/arm64/boot/dts/renesas
./arch/arm64/boot/dts/rockchip
./arch/arm64/boot/dts/ti
./arch/arm64/boot/dts/xilinx
./arch/arm/boot/dts/nxp/imx
./arch/arm/boot/dts/ti/omap
./drivers/clk
./drivers/of
./drivers/of/unittest-data
Out of these, `drivers/of` and `drivers/of/unittest-data` contain unittest dtso, so probably not the place.
And the `arch/arm` and `arch/arm64` are for arch specific stuff. MikroBUS is supported in RISC-V boards as well (BeagleV-Ahead). So probably not the correct location either.
Maybe something like `arch/common/addon_boards` would be better?
Ayush Singh
Odd top-level directory for the kernel, are you sure this is correct?
thanks,
greg k-h
Well, it is kinda a temporary location, since well, I could not find a good
place for board overlays but a top-level location seems better than putting
them in any arch specific location. I am open to moving them to a more
suitable location if we have one.
top-level location is not ok for something so tiny and "special". Just
put it where all other dtso files go.
thanks,
greg k-h
So here are the directories where dtso files currently go:
❯ find . -type f -name "*.dtso" -printf "%h\n" | sort -u
./arch/arm64/boot/dts/amlogic
./arch/arm64/boot/dts/freescale
./arch/arm64/boot/dts/mediatek
./arch/arm64/boot/dts/qcom
./arch/arm64/boot/dts/renesas
./arch/arm64/boot/dts/rockchip
./arch/arm64/boot/dts/ti
./arch/arm64/boot/dts/xilinx
./arch/arm/boot/dts/nxp/imx
./arch/arm/boot/dts/ti/omap
./drivers/clk
./drivers/of
./drivers/of/unittest-data
Out of these, `drivers/of` and `drivers/of/unittest-data` contain unittest dtso, so probably not the place.
And the `arch/arm` and `arch/arm64` are for arch specific stuff. MikroBUS is supported in RISC-V boards as well (BeagleV-Ahead). So probably not the correct location either.
Maybe something like `arch/common/addon_boards` would be better?
Whats about
drivers/misc/mikrobus/mikrobus.rs
drivers/misc/mikrobus/mikroe-1714.dtso
drivers/misc/mikrobus/mikroe-5761-i2c.dtso
?
Dirk
Odd top-level directory for the kernel, are you sure this is correct?
thanks,
greg k-h
Well, it is kinda a temporary location, since well, I could not
find a good
place for board overlays but a top-level location seems better
than putting
them in any arch specific location. I am open to moving them to a more
suitable location if we have one.
top-level location is not ok for something so tiny and "special". Just
put it where all other dtso files go.
thanks,
greg k-h
So here are the directories where dtso files currently go:
❯ find . -type f -name "*.dtso" -printf "%h\n" | sort -u
./arch/arm64/boot/dts/amlogic
./arch/arm64/boot/dts/freescale
./arch/arm64/boot/dts/mediatek
./arch/arm64/boot/dts/qcom
./arch/arm64/boot/dts/renesas
./arch/arm64/boot/dts/rockchip
./arch/arm64/boot/dts/ti
./arch/arm64/boot/dts/xilinx
./arch/arm/boot/dts/nxp/imx
./arch/arm/boot/dts/ti/omap
./drivers/clk
./drivers/of
./drivers/of/unittest-data
Out of these, `drivers/of` and `drivers/of/unittest-data` contain
unittest dtso, so probably not the place.
And the `arch/arm` and `arch/arm64` are for arch specific stuff.
MikroBUS is supported in RISC-V boards as well (BeagleV-Ahead). So
probably not the correct location either.
Maybe something like `arch/common/addon_boards` would be better?
Whats about
drivers/misc/mikrobus/mikrobus.rs
drivers/misc/mikrobus/mikroe-1714.dtso
drivers/misc/mikrobus/mikroe-5761-i2c.dtso
Exactly, put them where the drivers are, like clk and of does.
thanks,
greg k-h
Odd top-level directory for the kernel, are you sure this is correct?
thanks,
greg k-h
Well, it is kinda a temporary location, since well, I could not
find a good
place for board overlays but a top-level location seems better
than putting
them in any arch specific location. I am open to moving them to a more
suitable location if we have one.
top-level location is not ok for something so tiny and "special". Just
put it where all other dtso files go.
thanks,
greg k-h
So here are the directories where dtso files currently go:
❯ find . -type f -name "*.dtso" -printf "%h\n" | sort -u
./arch/arm64/boot/dts/amlogic
./arch/arm64/boot/dts/freescale
./arch/arm64/boot/dts/mediatek
./arch/arm64/boot/dts/qcom
./arch/arm64/boot/dts/renesas
./arch/arm64/boot/dts/rockchip
./arch/arm64/boot/dts/ti
./arch/arm64/boot/dts/xilinx
./arch/arm/boot/dts/nxp/imx
./arch/arm/boot/dts/ti/omap
./drivers/clk
./drivers/of
./drivers/of/unittest-data
Out of these, `drivers/of` and `drivers/of/unittest-data` contain
unittest dtso, so probably not the place.
And the `arch/arm` and `arch/arm64` are for arch specific stuff.
MikroBUS is supported in RISC-V boards as well (BeagleV-Ahead). So
probably not the correct location either.
Maybe something like `arch/common/addon_boards` would be better?
Whats about
drivers/misc/mikrobus/mikrobus.rs
drivers/misc/mikrobus/mikroe-1714.dtso
drivers/misc/mikrobus/mikroe-5761-i2c.dtso
Exactly, put them where the drivers are, like clk and of does.
thanks,
greg k-h
So I am writing a more thorough reply in the driver questions, but essentially, the driver is not actually required for using the overlay based approach for mikroBUS addon boards. Initially, the driver was not supposed to be included in the patch series at all. But I was not able to find a way to use a GPIO nexus node [0] without having a platform driver attached to the node.
In fact, if the GPIO nexus node is not required (like in the case of weather click), there is no need to even have a mikrobus-connector node in dt, let alone a driver.
So to answer why it probably should not go in the driver directory, the driver for the connector, actually does not register the mikrobus addon board. And if there is a way to have GPIO nexus node without having a platform driver attached to the node, then it should probably be removed.
The reason why the overlay based approach was suggested was because previous approaches could not do board stacking (having chain of mikrobus connector -> grove connector addon board -> grove board). So as you can see, it is beneficial to have grove board overlays compiled even in a board without any grove connectors because of stacking.
[0]: https://devicetree-specification.readthedocs.io/en/v0.3/devicetree-basics.html#nexus-nodes-and-specifier-mapping
Ayush Singh
Odd top-level directory for the kernel, are you sure this is correct?
I am open to moving them to a more suitable location if we have one.
So here are the directories where dtso files currently go:
❯ find . -type f -name "*.dtso" -printf "%h\n" | sort -u
Out of these, `drivers/of` and `drivers/of/unittest-data` contain
unittest dtso, so probably not the place.
And the `arch/arm` and `arch/arm64` are for arch specific stuff.
MikroBUS is supported in RISC-V boards as well (BeagleV-Ahead). So
probably not the correct location either.
Maybe something like `arch/common/addon_boards` would be better?
Whats about
drivers/misc/mikrobus/mikrobus.rs
drivers/misc/mikrobus/mikroe-1714.dtso
drivers/misc/mikrobus/mikroe-5761-i2c.dtso
Exactly, put them where the drivers are, like clk and of does.
thanks,
greg k-h
So I am writing a more thorough reply in the driver questions,
As I did read it,
is it not "driver questions" but about "location of new files"
and "bus versus device"
but essentially, the driver is not actually required for using the
overlay based approach for mikroBUS addon boards. Initially, the driver
was not supposed to be included in the patch series at all. But I was
not able to find a way to use a GPIO nexus node [0] without having a
platform driver attached to the node.
In fact, if the GPIO nexus node is not required (like in the case of
weather click), there is no need to even have a mikrobus-connector
node in dt, let alone a driver.
So to answer why it probably should not go in the driver directory,
the driver for the connector, actually does not register the mikrobus
addon board. And if there is a way to have GPIO nexus node without
having a platform driver attached to the node, then it should probably
be removed.
The reason why the overlay based approach was suggested was because
previous approaches could not do board stacking (having chain of
mikrobus connector -> grove connector addon board -> grove board). So
as you can see, it is beneficial to have grove board overlays compiled
even in a board without any grove connectors because of stacking.
On Wed, Sep 11, 2024 at 09:32:21PM +0530, Ayush Singh wrote:
quoted
On 9/11/24 20:27, Greg Kroah-Hartman wrote:
quoted
On Wed, Sep 11, 2024 at 07:57:20PM +0530, Ayush Singh wrote:
quoted
A simple platform driver for now that does nothing. This is required
because without a platform driver, the mikrobus_gpio0 nexus node cannot
be used.
In future, this driver will also allow for dynamic board detection using
1-wire eeprom in new mikrobus boards.
Signed-off-by: Ayush Singh <redacted>
---
MAINTAINERS | 1 +
drivers/misc/Kconfig | 17 +++++++++++++++++
drivers/misc/Makefile | 1 +
drivers/misc/mikrobus.rs | 32 ++++++++++++++++++++++++++++++++
4 files changed, 51 insertions(+)
@@ -610,6 +610,23 @@ config MARVELL_CN10K_DPITocompilethisdriverasamodule,chooseMhere:themodulewillbecalledmrvl_cn10k_dpi.+menuconfigMIKROBUS+tristate"Module for instantiating devices on mikroBUS ports"+help+ThisoptionenablesthemikroBUSdriver.mikroBUSisanadd-on+boardsocketstandardthatoffersmaximumexpandabilitywith+thesmallestnumberofpins.ThemikroBUSdriverinstantiates+devicesonamikroBUSportdescribedbyidentifyingdatapresent+inanadd-onboardresidentEEPROM,moredetailsonthemikroBUS+driversupportanddiscussioncanbefoundinthiseLinuxwiki:+elinux.org/Mikrobus
So you want to be a bus? Or just a single driver? I'm confused, what
exactly is this supposed to do?
If a bus, great, let's tie into the proper driver core bus code, don't
"open code" all of that, as that's just going to make things messier and
harder to work overall in the end.
If a single driver, why is it called "bus"? :)
thanks,
greg k-h
Well, mikroBUS [0] is the name of the socket standard. It is basically a
group of following pins:
Analog - AN
Reset - RST
SPI Chip Select - CS
SPI Clock - SCK
SPI Master Input Slave Output - MISO
SPI Master Output Slave Input - MOSI
VCC-3.3V power - +3.3V
Reference Ground - GND
PWM - PWM output
INT - Hardware Interrupt
RX - UART Receive
TX - UART Transmit
SCL - I2C Clock
SDA - I2C Data
+5V - VCC-5V power
GND - Reference Ground
I do not think it would qualify as as a "bus" in the Linux driver sense.
Especially with the devicetree based approach here which applies overlay
directly to the actual uart/i2c/spi controllers and basically not interact
with the mikroBUS node much.
It will be a "bus" in the driver sense as you want to have different
drivers bound to devices that are plugged in here, right? Or if this is
just a single driver for the hardware, then no, as you will not have any
additional drivers for this standard? It's unclear you want to do here.
No, a single driver. The driver is for board detection and applying proper overlay. There will not be separate drivers for each addon board.
quoted
The driver is here to enable the following:
1. Enable dynamic board detection using 1-wire eeprom on some addon boards.
Some, not all?
Some mikroBUS boards have 1-wire eeprom [0]. This can be used to enable dynamic detection of the board. But this is not part of mikroBUS specification itself, and is like a mikroe addition. So there will be a lot of mikrobus addon boards that do not have any way to do dynamic detection.
quoted
2. Provide sysfs entry for runtime board adding/removal
That's not what sysfs is for, but we can get there eventually...
quoted
3. Enable using mikrobus connector node as nexus node for GPIO (not having a
platform driver makes any driver trying to use the connector as nexus node
go into deffered probing state).
Why is this a platform device? Is this always going to be described by
DT somehow?
Well, since greybus does not use a dt based approach right now, that is one case where we potentially cannot describe the connector in DT. But since greybus is mostly staging, I am not sure if there are any plans to use DT before bringing it to mainline.
quoted
For this patch series, the driver is mostly here due to point 3. Basically a
stub.
Let's see how this really works before coming to conclusions.
As an example, how do you think sysfs should look for this device? For
all devices? Write out the needed sysfs documentation entries first and
then that will help explain things better.
thanks,
greg k-h
Something like the following:
cat board-overlay.dtbo > /sys/bus/platform/mikrobus-connector0/new_device
And to remove the device (revert the overlay)
echo 1 > /sys/bus/platform/mikrobus-connector0/delete_device
The main motivation for the sysfs entry is that only the board overlay needs to be provided, since the driver already knows it's own connector (and hence the symbols overlay for the connector).
[0]: https://github.com/MikroElektronika/click_id
Ayush Singh
From: Alexander Stein <hidden> Date: 2024-09-13 10:05:17
Hi,
Am Mittwoch, 11. September 2024, 16:27:17 CEST schrieb Ayush Singh:
Hello all,
This is an attempt to add MikroBUS addon support using the approach
described by Grove connector patch series [0].
The patch series tests out 2 addon boards + pwm and GPIO on the MikroBUS
connector. The boards used are GPS3 Click (for UART) [1] and Weather
Click (for I2C) [2]. Additionally, I have tested relative GPIO numbering
using devicetree nexus nodes [3].
The patch series does not attempt to do any dynamic discovery for 1-wire
eeprom MikroBUS addon boards, nor does it provide any sysfs entry for
board addition/removal. The connector driver might include them after
the basic support is ironed out, but the existing patches for dynamic
overlays work fine.
[sniip]
To put it in a more abstract perspective, aren't you "just" defining some
kind of connector with a fixed layout of pins and features?
It's not really different to Arduino Shields and Raspberry Pi hats, no?
Ignoring multi-purpose pins for GPIO or e.g. I2C, this is about matching
the plugin module's pins to platform-specific on-board peripherals.
Sticking the name to MikroBUS might be misleading, because this is AFAICT
just a trademark for a specific connector pin layout.
This concept could be applied for any kind of connector, where e.g.
the I2C interface is mapped to i2c0 on one platform and to lpi2c5
on a different platform.
Best regards,
Alexander
--
TQ-Systems GmbH | Mühlstraße 2, Gut Delling | 82229 Seefeld, Germany
Amtsgericht München, HRB 105018
Geschäftsführer: Detlef Schneider, Rüdiger Stahl, Stefan Schneider
http://www.tq-group.com/
Hi,
Am Mittwoch, 11. September 2024, 16:27:17 CEST schrieb Ayush Singh:
quoted
Hello all,
This is an attempt to add MikroBUS addon support using the approach
described by Grove connector patch series [0].
The patch series tests out 2 addon boards + pwm and GPIO on the MikroBUS
connector. The boards used are GPS3 Click (for UART) [1] and Weather
Click (for I2C) [2]. Additionally, I have tested relative GPIO numbering
using devicetree nexus nodes [3].
The patch series does not attempt to do any dynamic discovery for 1-wire
eeprom MikroBUS addon boards, nor does it provide any sysfs entry for
board addition/removal. The connector driver might include them after
the basic support is ironed out, but the existing patches for dynamic
overlays work fine.
[sniip]
To put it in a more abstract perspective, aren't you "just" defining some
kind of connector with a fixed layout of pins and features?
It's not really different to Arduino Shields and Raspberry Pi hats, no?
Ignoring multi-purpose pins for GPIO or e.g. I2C, this is about matching
the plugin module's pins to platform-specific on-board peripherals.
Sticking the name to MikroBUS might be misleading, because this is AFAICT
just a trademark for a specific connector pin layout.
This concept could be applied for any kind of connector, where e.g.
the I2C interface is mapped to i2c0 on one platform and to lpi2c5
on a different platform.
Best regards,
Alexander
Yes, the only thing specific to mikroBUS in the patches is the connector symbols. Theoretically, it is supposed to be usable with any connector. MikroBUS is just the connector I am trying to apply the concept to.
I think I came across a bit too mikroBUS specific in the patches here, since well that is the connector I am currently trying to support, but as the original patches by Andrew [0] explain, this approach was proposed to work as a generic way to support such connectors, and even do connector stacking.
Trying to use it with MikroBUS shows some limitations we have with the current device tree stuff
1. SPI chipselect
2. Nexus nodes need the node to have some kind of existing driver
3. A good place to store the board overlays
4. Stacking needs phandle symbols table support
5. Append property support in devicetree
And of course, I might encounter more limitations as I continue to test more boards with it.
[0]: https://lore.kernel.org/linux-arm-kernel/20240702164403.29067-1-afd@ti.com/
Ayush Singh
From: Janne Grunau <hidden> Date: 2024-09-14 10:11:53
On Wed, Sep 11, 2024 at 07:35:35PM +0200, Danilo Krummrich wrote:
On Wed, Sep 11, 2024 at 04:56:14PM +0200, Greg Kroah-Hartman wrote:
quoted
On Wed, Sep 11, 2024 at 07:57:18PM +0530, Ayush Singh wrote:
quoted
+/// An identifier for Platform devices.+///+/// Represents the kernel's [`struct of_device_id`]. This is used to find an appropriate+/// Platform driver.+///+/// [`struct of_device_id`]: srctree/include/linux/mod_devicetable.h+pub struct DeviceId(&'static CStr);++impl DeviceId {
<snip>
I appreciate posting this, but this really should go on top of the
device driver work Danilo Krummrich has been doing.
If everyone agrees, I'd offer to just provide platform device / driver
abstractions with my next patch series. This way you don't need to worry
about aligning things with the rest of the abstractions yourself and throughout
potential further versions of the series.
Covering platform device/driver abstractions in the same series would
be appreciated from asahi side. It hopefully results in earlier merge
since it avoids a dependency on the device driver abstractions.
Feel free to reach out to me for an earlier preview / rabsing of the
asahi driver.
https://github.com/AsahiLinux/linux/tree/bits/210-gpu has all relevant
rust changes from 6.11-rc but I plan to rebase onto 6.11 in the next
days and possibly import changes from 6.12-rc* / rust-next.
Thanks
Janne
On Wed, Sep 11, 2024 at 07:57:17PM +0530, Ayush Singh wrote:
quoted
Hello all,
This is an attempt to add MikroBUS addon support using the approach
described by Grove connector patch series [0].
The patch series tests out 2 addon boards + pwm and GPIO on the MikroBUS
connector. The boards used are GPS3 Click (for UART) [1] and Weather
Click (for I2C) [2]. Additionally, I have tested relative GPIO numbering
using devicetree nexus nodes [3].
The patch series does not attempt to do any dynamic discovery for 1-wire
eeprom MikroBUS addon boards, nor does it provide any sysfs entry for
board addition/removal. The connector driver might include them after
the basic support is ironed out, but the existing patches for dynamic
overlays work fine.
The patch series has been tested on BeaglePlay [4].
I will now go over individual parts of the patch series, but for a
better picture of the approach, it would be best to checkout [0] first.
MikroBUS connector driver
-------------------------
Just a stub platform driver for now. Will be extended in the future for
dynamic board discovery using 1-wire eeprom present in some MikroBUS
addon boards.
While it is a stub driver, disabling it will make the GPIO connector
nexus node unreachable (any driver attempting to use it will enter
differed probing). So it is required.
MikroBUS connector Devicetree
------------------------------
The connector devicetree defines the MikroBUS GPIO nexus node. This
allows using pin numbering relative to MikroBUS connector pins in the
addon boards overlay. Currently, the patch uses a clockwise numbering:
0: PWM
1: INT
2: RX
3: TX
4: SCL
5: SDA
6: MOSI
7: MISO
8: SCK
9: CS
10: RST
11: AN
Additionally, in case PWM pin is not using channel 0, a nexus node for pwm
should also be used and go in the connector devicetree.
MikroBUS connector symbols overlay
----------------------------------
To make an overlay generic we need a standard name scheme which we
use across base boards. For the connector pins the pinmux phandle
shall be:
<connector-name>_<pin-name>_mux_<pin-function>
For the parent provider phandle, we use a similar naming scheme:
<connector-name>_<pin-name>_<pin-function>
For GPIO controller, I am using `MIKROBUS_GPIO` name since with nexus
nodes, we do not need to define individual pin gpio controllers.
The string symbols can be replaced with phandles once [5] is accepted.
That will make connector stacking much simpler.
MikroBUS addon board overlay
----------------------------
The patch puts the addon board overlays in their own directory. I am
using the following naming scheme for MikroBUS addon boards:
<vendor>-<product_id>.dtso
Mikroe [6] lists this for all boards in their website, but I am not sure
if other vendors have a product_id.
This naming also makes future dynamic discovery easier, since click id
spec [7] contains vendor_id and product_id in the header.
Usage
-----
So what does this all look like? Let's take an example of a BeaglePlay
with one MikroBUS connectors for which we have physically attached a
Wather click module to the first connector. Doing ahead of time
command-line DT overlay application:
./fdtoverlay \
-o output.dtb \
-i k3-am625-beagleplay.dtb \
k3-am625-beagleplay-mikrobus-connector0.dtbo mikroe-5761.dtbo
Open Items
----------
- SPI Support:
Currently SPI dt requires `reg` property to specify the
chipselect to use. This, makes the SPI device overlay dependent on the
SPI controller. Thus for SPI support, we need a way to allow defining
SPI chipselect relative to MikroBUS pins, and not the actual device
controller.
One possible solution is to introduce something like `named-reg` and
allow selecting the chipselect by string array. But this probably
requires more discussion so I have left out SPI support for now.
NOTE: pins other than the CS MikroBUS pin can be used as chipselect.
See [8].
- Controller symbol duplication
The current symbol scheme has multiple symbols for the same underlying
controller (Eg: MIKROBUS_SCL_MUX_I2C_SCL and MIKROBUS_SDA_MUX_I2C_SDA)
point to the same i2c controller.
I think both of them will always use the same i2c controller, but
maybe there are some exceptions? So I have left it as it is for this
patch series. The same thing also applies to UART and SPI.
NOTE: with the use of nexus node for GPIO, the GPIO controller symbol
will be the same for all pins.
- Nexus node dt-bindings
I am not quite sure how to deal with the nexus node properties
(#gpio-cells, gpio-map, gpio-map-mask, gpio-map-pass-thru) since they
seem to conflict with upstream gpio schema (gpio-controller is a
dependency of #gpio-cells).
Please submit a fix to dtschema. Either GH PR or patch to
devicetree-spec list.
Rob