#include "core.h"
#define DRIVER_NAME "pinctrl-single"
-#define PCS_MUX_NAME "pinctrl-single,pins"
+#define PCS_MUX_PINS_NAME "pinctrl-single,pins"
+#define PCS_MUX_BITS_NAME "pinctrl-single,bits"
#define PCS_REG_NAME_LEN ((sizeof(unsigned long) * 2) + 1)
#define PCS_OFF_DISABLED ~0U
struct pcs_func_vals {
void __iomem *reg;
unsigned val;
+ unsigned mask;
};
/**
unsigned fshift;
unsigned foff;
unsigned fmax;
+ bool bits_per_mux;
struct pcs_name *names;
struct pcs_data pins;
struct radix_tree_root pgtree;
struct seq_file *s,
unsigned offset)
{
- seq_printf(s, " " DRIVER_NAME);
+ struct pcs_device *pcs;
+ unsigned val;
+
+ pcs = pinctrl_dev_get_drvdata(pctldev);
+
+ val = pcs->read(pcs->base + offset);
+ val &= pcs->fmask;
+
+ seq_printf(s, "%08x %s " , val, DRIVER_NAME);
}
static void pcs_dt_free_map(struct pinctrl_dev *pctldev,
for (i = 0; i < func->nvals; i++) {
struct pcs_func_vals *vals;
- unsigned val;
+ unsigned val, mask;
vals = &func->vals[i];
val = pcs->read(vals->reg);
- val &= ~pcs->fmask;
- val |= vals->val;
+ if (!vals->mask)
+ mask = pcs->fmask;
+ else
+ mask = pcs->fmask & vals->mask;
+
+ val &= ~mask;
+ val |= (vals->val & mask);
pcs->write(val, vals->reg);
}
{
struct pcs_func_vals *vals;
const __be32 *mux;
- int size, rows, *pins, index = 0, found = 0, res = -ENOMEM;
+ int size, params, rows, *pins, index = 0, found = 0, res = -ENOMEM;
struct pcs_function *function;
- mux = of_get_property(np, PCS_MUX_NAME, &size);
- if ((!mux) || (size < sizeof(*mux) * 2)) {
- dev_err(pcs->dev, "bad data for mux %s\n",
- np->name);
+ if (pcs->bits_per_mux) {
+ params = 3;
+ mux = of_get_property(np, PCS_MUX_BITS_NAME, &size);
+ } else {
+ params = 2;
+ mux = of_get_property(np, PCS_MUX_PINS_NAME, &size);
+ }
+
+ if (!mux) {
+ dev_err(pcs->dev, "no valid property for %s\n", np->name);
+ return -EINVAL;
+ }
+
+ if (size < (sizeof(*mux) * params)) {
+ dev_err(pcs->dev, "bad data for %s\n", np->name);
return -EINVAL;
}
size /= sizeof(*mux); /* Number of elements in array */
- rows = size / 2; /* Each row is a key value pair */
+ rows = size / params;
vals = devm_kzalloc(pcs->dev, sizeof(*vals) * rows, GFP_KERNEL);
if (!vals)
val = be32_to_cpup(mux + index++);
vals[found].reg = pcs->base + offset;
vals[found].val = val;
+ if (params == 3) {
+ val = be32_to_cpup(mux + index++);
+ vals[found].mask = val;
+ }
pin = pcs_get_pin_by_offset(pcs, offset);
if (pin < 0) {
if (ret)
pcs->foff = PCS_OFF_DISABLED;
+ pcs->bits_per_mux = of_property_read_bool(np,
+ "pinctrl-single,bit-per-mux");
+
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
if (!res) {
dev_err(pcs->dev, "could not get resource\n");