* Re: [PATCH RESEND 2/2] gpio: axp209: add pinctrl support
From: kbuild test robot @ 2016-11-24 0:00 UTC (permalink / raw)
Cc: kbuild-all-JC7UmRfGjtg, linus.walleij-QSEj5FYQhm4dnm+yROfE0A,
gnurou-Re5JQEeQqe8AvxtiuMwx3w, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, wens-jdAy2FN1RRM,
maxime.ripard-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8, Quentin Schulz,
linux-gpio-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r
In-Reply-To: <20161123141151.25315-3-quentin.schulz-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
[-- Attachment #1: Type: text/plain, Size: 18004 bytes --]
Hi Quentin,
[auto build test ERROR on gpio/for-next]
[also build test ERROR on v4.9-rc6 next-20161123]
[if your patch is applied to the wrong git tree, please drop us a note to help improve the system]
url: https://github.com/0day-ci/linux/commits/Quentin-Schulz/add-support-for-AXP209-GPIOs-functions/20161124-061409
base: https://git.kernel.org/pub/scm/linux/kernel/git/linusw/linux-gpio.git for-next
config: tile-allmodconfig (attached as .config)
compiler: tilegx-linux-gcc (GCC) 4.6.2
reproduce:
wget https://git.kernel.org/cgit/linux/kernel/git/wfg/lkp-tests.git/plain/sbin/make.cross -O ~/bin/make.cross
chmod +x ~/bin/make.cross
# save the attached .config to linux build tree
make.cross ARCH=tile
All errors (new ones prefixed by >>):
drivers/gpio/gpio-axp209.c:100:2: error: field name not in record or union initializer
drivers/gpio/gpio-axp209.c:100:2: error: (near initialization for
drivers/gpio/gpio-axp209.c:100:2: error: field name not in record or union initializer
drivers/gpio/gpio-axp209.c:100:2: error: (near initialization for
drivers/gpio/gpio-axp209.c:100:2: error: field name not in record or union initializer
drivers/gpio/gpio-axp209.c:100:2: error: (near initialization for
drivers/gpio/gpio-axp209.c:105:2: error: field name not in record or union initializer
drivers/gpio/gpio-axp209.c:105:2: error: (near initialization for
drivers/gpio/gpio-axp209.c:105:2: error: field name not in record or union initializer
drivers/gpio/gpio-axp209.c:105:2: error: (near initialization for
drivers/gpio/gpio-axp209.c:105:2: error: field name not in record or union initializer
drivers/gpio/gpio-axp209.c:105:2: error: (near initialization for
drivers/gpio/gpio-axp209.c: In function 'axp20x_gpio_get_direction':
drivers/gpio/gpio-axp209.c:131:49: error: request for member 'drv_data' in something not a structure or union
drivers/gpio/gpio-axp209.c:131:16: warning: cast from pointer to integer of different size
drivers/gpio/gpio-axp209.c: In function 'axp20x_gpio_set':
drivers/gpio/gpio-axp209.c:158:49: error: request for member 'drv_data' in something not a structure or union
drivers/gpio/gpio-axp209.c:158:16: warning: cast from pointer to integer of different size
drivers/gpio/gpio-axp209.c: In function 'axp20x_gpio_input':
drivers/gpio/gpio-axp209.c:168:2: error: implicit declaration of function 'pinctrl_gpio_direction_input'
drivers/gpio/gpio-axp209.c: In function 'axp20x_pmx_set':
drivers/gpio/gpio-axp209.c:182:9: error: implicit declaration of function 'pinctrl_dev_get_drvdata'
drivers/gpio/gpio-axp209.c:182:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c:183:49: error: request for member 'drv_data' in something not a structure or union
drivers/gpio/gpio-axp209.c:183:16: warning: cast from pointer to integer of different size
drivers/gpio/gpio-axp209.c: In function 'axp20x_pmx_func_cnt':
drivers/gpio/gpio-axp209.c:191:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_pmx_func_name':
drivers/gpio/gpio-axp209.c:199:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_pmx_func_groups':
drivers/gpio/gpio-axp209.c:209:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_pinctrl_desc_find_func_by_name':
drivers/gpio/gpio-axp209.c:228:23: error: request for member 'name' in something not a structure or union
drivers/gpio/gpio-axp209.c:228:3: warning: passing argument 1 of 'strcmp' from incompatible pointer type [enabled by default]
include/linux/string.h:42:12: note: expected 'const char but argument is of type 'const struct axp20x_desc_pin
drivers/gpio/gpio-axp209.c: In function 'axp20x_pmx_set_mux':
drivers/gpio/gpio-axp209.c:253:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_pctl_desc_find_func_by_pin':
drivers/gpio/gpio-axp209.c:276:15: error: request for member 'number' in something not a structure or union
drivers/gpio/gpio-axp209.c:276:23: warning: comparison between pointer and integer [enabled by default]
drivers/gpio/gpio-axp209.c: At top level:
drivers/gpio/gpio-axp209.c:293:7: warning: 'struct pinctrl_gpio_range' declared inside parameter list [enabled by default]
drivers/gpio/gpio-axp209.c:293:7: warning: its scope is only this definition or declaration, which is probably not what you want [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_pmx_gpio_set_direction':
drivers/gpio/gpio-axp209.c:295:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: At top level:
drivers/gpio/gpio-axp209.c:311:21: error: variable 'axp20x_pmx_ops' has initializer but incomplete type
drivers/gpio/gpio-axp209.c:312:2: error: unknown field 'get_functions_count' specified in initializer
drivers/gpio/gpio-axp209.c:312:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:312:2: warning: (near initialization for 'axp20x_pmx_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:313:2: error: unknown field 'get_function_name' specified in initializer
drivers/gpio/gpio-axp209.c:313:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:313:2: warning: (near initialization for 'axp20x_pmx_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:314:2: error: unknown field 'get_function_groups' specified in initializer
drivers/gpio/gpio-axp209.c:314:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:314:2: warning: (near initialization for 'axp20x_pmx_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:315:2: error: unknown field 'set_mux' specified in initializer
drivers/gpio/gpio-axp209.c:315:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:315:2: warning: (near initialization for 'axp20x_pmx_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:316:2: error: unknown field 'gpio_set_direction' specified in initializer
drivers/gpio/gpio-axp209.c:316:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:316:2: warning: (near initialization for 'axp20x_pmx_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:317:2: error: unknown field 'strict' specified in initializer
drivers/gpio/gpio-axp209.c:317:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:317:2: warning: (near initialization for 'axp20x_pmx_ops') [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_groups_cnt':
drivers/gpio/gpio-axp209.c:322:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_group_pins':
drivers/gpio/gpio-axp209.c:330:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_group_name':
drivers/gpio/gpio-axp209.c:342:29: warning: initialization makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: At top level:
drivers/gpio/gpio-axp209.c:347:21: error: variable 'axp20x_pctrl_ops' has initializer but incomplete type
drivers/gpio/gpio-axp209.c:348:2: error: unknown field 'dt_node_to_map' specified in initializer
drivers/gpio/gpio-axp209.c:348:21: error: 'pinconf_generic_dt_node_to_map_group' undeclared here (not in a function)
drivers/gpio/gpio-axp209.c:348:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:348:2: warning: (near initialization for 'axp20x_pctrl_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:349:2: error: unknown field 'dt_free_map' specified in initializer
drivers/gpio/gpio-axp209.c:349:18: error: 'pinconf_generic_dt_free_map' undeclared here (not in a function)
drivers/gpio/gpio-axp209.c:349:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:349:2: warning: (near initialization for 'axp20x_pctrl_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:350:2: error: unknown field 'get_groups_count' specified in initializer
drivers/gpio/gpio-axp209.c:350:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:350:2: warning: (near initialization for 'axp20x_pctrl_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:351:2: error: unknown field 'get_group_name' specified in initializer
drivers/gpio/gpio-axp209.c:351:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:351:2: warning: (near initialization for 'axp20x_pctrl_ops') [enabled by default]
drivers/gpio/gpio-axp209.c:352:2: error: unknown field 'get_group_pins' specified in initializer
drivers/gpio/gpio-axp209.c:352:2: warning: excess elements in struct initializer [enabled by default]
drivers/gpio/gpio-axp209.c:352:2: warning: (near initialization for 'axp20x_pctrl_ops') [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_attach_group_function':
drivers/gpio/gpio-axp209.c:416:23: error: request for member 'name' in something not a structure or union
drivers/gpio/gpio-axp209.c:416:13: warning: assignment from incompatible pointer type [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_build_state':
drivers/gpio/gpio-axp209.c:439:49: error: request for member 'name' in something not a structure or union
drivers/gpio/gpio-axp209.c:439:24: warning: assignment from incompatible pointer type [enabled by default]
drivers/gpio/gpio-axp209.c:440:48: error: request for member 'number' in something not a structure or union
drivers/gpio/gpio-axp209.c:440:23: warning: assignment makes integer from pointer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c: In function 'axp20x_pctl_probe':
drivers/gpio/gpio-axp209.c:522:61: error: dereferencing pointer to incomplete type
>> drivers/gpio/gpio-axp209.c:522:52: error: invalid operands to binary Makefile arch drivers include kernel scripts source (have 'int' and 'const struct axp20x_desc_pin
drivers/gpio/gpio-axp209.c:523:8: warning: passing argument 2 of 'devm_kzalloc' makes integer from pointer without a cast [enabled by default]
include/linux/device.h:658:21: note: expected 'size_t' but argument is of type 'const struct axp20x_desc_pin
drivers/gpio/gpio-axp209.c:528:3: error: invalid use of undefined type 'struct pinctrl_pin_desc'
drivers/gpio/gpio-axp209.c:528:7: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:528:3: warning: statement with no effect
drivers/gpio/gpio-axp209.c:530:47: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:530:2: warning: passing argument 2 of 'devm_kzalloc' makes integer from pointer without a cast [enabled by default]
include/linux/device.h:658:21: note: expected 'size_t' but argument is of type 'const struct axp20x_desc_pin
drivers/gpio/gpio-axp209.c:534:12: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:534:12: error: request for member 'name' in something not a structure or union
drivers/gpio/gpio-axp209.c:534:2: warning: statement with no effect
drivers/gpio/gpio-axp209.c:535:12: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:535:12: error: request for member 'owner' in something not a structure or union
drivers/gpio/gpio-axp209.c:535:2: warning: statement with no effect
drivers/gpio/gpio-axp209.c:536:12: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:536:12: error: request for member 'pins' in something not a structure or union
drivers/gpio/gpio-axp209.c:536:2: warning: statement with no effect
drivers/gpio/gpio-axp209.c:537:12: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:537:12: error: request for member 'npins' in something not a structure or union
drivers/gpio/gpio-axp209.c:537:2: warning: statement with no effect
drivers/gpio/gpio-axp209.c:538:12: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:538:12: error: request for member 'pctlops' in something not a structure or union
drivers/gpio/gpio-axp209.c:538:2: warning: statement with no effect
drivers/gpio/gpio-axp209.c:539:12: error: dereferencing pointer to incomplete type
drivers/gpio/gpio-axp209.c:539:12: error: request for member 'pmxops' in something not a structure or union
drivers/gpio/gpio-axp209.c:539:2: warning: statement with no effect
drivers/gpio/gpio-axp209.c:541:2: error: implicit declaration of function 'devm_pinctrl_register'
drivers/gpio/gpio-axp209.c:541:17: warning: assignment makes pointer from integer without a cast [enabled by default]
drivers/gpio/gpio-axp209.c:557:19: error: request for member 'number' in something not a structure or union
drivers/gpio/gpio-axp209.c:557:36: error: request for member 'number' in something not a structure or union
drivers/gpio/gpio-axp209.c:558:11: warning: passing argument 3 of 'gpiochip_add_pin_range' makes integer from pointer without a cast [enabled by default]
include/linux/gpio/driver.h:324:1: note: expected 'unsigned int' but argument is of type 'const struct axp20x_desc_pin
drivers/gpio/gpio-axp209.c:558:11: warning: passing argument 4 of 'gpiochip_add_pin_range' makes integer from pointer without a cast [enabled by default]
include/linux/gpio/driver.h:324:1: note: expected 'unsigned int' but argument is of type 'const struct axp20x_desc_pin
cc1: some warnings being treated as errors
vim +522 drivers/gpio/gpio-axp209.c
410 }
411
412 func_grp = func->groups;
413 while (*func_grp)
414 func_grp++;
415
> 416 *func_grp = pin->pin.name;
417 desc_func++;
418 }
419
420 return 0;
421 }
422
423 static int axp20x_build_state(struct platform_device *pdev)
424 {
425 struct axp20x_pctl *pctl = platform_get_drvdata(pdev);
426 unsigned int npins = pctl->desc->npins;
427 const struct axp20x_desc_pin *pin;
428 struct axp20x_desc_function *func;
429 int i, ret;
430
431 pctl->ngroups = npins;
432 pctl->groups = devm_kzalloc(&pdev->dev,
433 pctl->ngroups * sizeof(*pctl->groups),
434 GFP_KERNEL);
435 if (!pctl->groups)
436 return -ENOMEM;
437
438 for (i = 0; i < npins; i++) {
439 pctl->groups[i].name = pctl->desc->pins[i].pin.name;
440 pctl->groups[i].pin = pctl->desc->pins[i].pin.number;
441 }
442
443 /* We assume 4 functions per pin should be enough as a default max */
444 pctl->functions = devm_kzalloc(&pdev->dev,
445 npins * 4 * sizeof(*pctl->functions),
446 GFP_KERNEL);
447 if (!pctl->functions)
448 return -ENOMEM;
449
450 /* Create a list of uniquely named functions */
451 for (i = 0; i < npins; i++) {
452 pin = &pctl->desc->pins[i];
453 func = pin->functions;
454
455 while (func->name) {
456 axp20x_pinctrl_add_function(pctl, func->name);
457 func++;
458 }
459 }
460
461 pctl->functions = krealloc(pctl->functions,
462 pctl->nfunctions * sizeof(*pctl->functions),
463 GFP_KERNEL);
464
465 for (i = 0; i < npins; i++) {
466 pin = &pctl->desc->pins[i];
467 ret = axp20x_attach_group_function(pdev, pin);
468 if (ret)
469 return ret;
470 }
471
472 return 0;
473 }
474
475 static int axp20x_pctl_probe(struct platform_device *pdev)
476 {
477 struct axp20x_dev *axp20x = dev_get_drvdata(pdev->dev.parent);
478 const struct axp20x_desc_pin *pin;
479 struct axp20x_pctl *pctl;
480 struct pinctrl_desc *pctrl_desc;
481 struct pinctrl_pin_desc *pins;
482 int ret, i;
483
484 if (!of_device_is_available(pdev->dev.of_node))
485 return -ENODEV;
486
487 if (!axp20x) {
488 dev_err(&pdev->dev, "Parent drvdata not set\n");
489 return -EINVAL;
490 }
491
492 pctl = devm_kzalloc(&pdev->dev, sizeof(*pctl), GFP_KERNEL);
493 if (!pctl)
494 return -ENOMEM;
495
496 pctl->chip.base = -1;
497 pctl->chip.can_sleep = true;
498 pctl->chip.request = gpiochip_generic_request;
499 pctl->chip.free = gpiochip_generic_free;
500 pctl->chip.parent = &pdev->dev;
501 pctl->chip.label = dev_name(&pdev->dev);
502 pctl->chip.owner = THIS_MODULE;
503 pctl->chip.get = axp20x_gpio_get;
504 pctl->chip.get_direction = axp20x_gpio_get_direction;
505 pctl->chip.set = axp20x_gpio_set;
506 pctl->chip.direction_input = axp20x_gpio_input;
507 pctl->chip.direction_output = axp20x_gpio_output;
508 pctl->chip.ngpio = 3;
509 pctl->chip.can_sleep = true;
510
511 pctl->regmap = axp20x->regmap;
512
513 pctl->desc = &axp20x_pinctrl_data;
514 pctl->dev = &pdev->dev;
515
516 platform_set_drvdata(pdev, pctl);
517
518 ret = axp20x_build_state(pdev);
519 if (ret)
520 return ret;
521
> 522 pins = devm_kzalloc(&pdev->dev, pctl->desc->npins * sizeof(*pins),
523 GFP_KERNEL);
524 if (!pins)
525 return -ENOMEM;
---
0-DAY kernel test infrastructure Open Source Technology Center
https://lists.01.org/pipermail/kbuild-all Intel Corporation
[-- Attachment #2: .config.gz --]
[-- Type: application/gzip, Size: 46296 bytes --]
^ permalink raw reply
* Re: [PATCH v4 1/2] i2c: aspeed: added driver for Aspeed I2C
From: Brendan Higgins @ 2016-11-23 23:52 UTC (permalink / raw)
To: Cédric Le Goater
Cc: Wolfram Sang, robh+dt, mark.rutland, devicetree, OpenBMC Maillist,
linux-i2c
In-Reply-To: <28078e6d-f5e4-da59-e226-baa9a60a4b19@kaod.org>
> is it safe to start a new transaction when in a interrupt handler ?
Yep, i2c_transfer and most of the other functions in the i2c API that
wrap the implementations already lock for you.
> Why do you multiply by * msg->len ?
I thought it might make sense to make timeout proportional to message
length, so their would be a timeout per byte, like what the hardware
already does. I guess we should just leave that up to the user to
determine on their own?
> use devm_kzalloc() may be ?
Whoops, good catch. Will update in next version.
^ permalink raw reply
* Re: [PATCH v3 3/4] [media] davinci: vpif_capture: get subdevs from DT
From: Kevin Hilman @ 2016-11-23 23:26 UTC (permalink / raw)
To: Sakari Ailus
Cc: linux-media, Hans Verkuil, devicetree, Sekhar Nori, Axel Haslam,
Bartosz Gołaszewski, Alexandre Bailon, David Lechner
In-Reply-To: <20161123153723.GE16630@valkosipuli.retiisi.org.uk>
Hi Sakari,
Sakari Ailus <sakari.ailus@iki.fi> writes:
> On Tue, Nov 22, 2016 at 07:52:43AM -0800, Kevin Hilman wrote:
>> Allow getting of subdevs from DT ports and endpoints.
>>
>> The _get_pdata() function was larely inspired by (i.e. stolen from)
>
> vpif_capture_get_pdata and "largely"?
Yes, thanks.
>> am437x-vpfe.c
>>
>> Signed-off-by: Kevin Hilman <khilman@baylibre.com>
>> ---
>> drivers/media/platform/davinci/vpif_capture.c | 130 +++++++++++++++++++++++++-
>> include/media/davinci/vpif_types.h | 9 +-
>> 2 files changed, 133 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
>> index 94ee6cf03f02..47a4699157e7 100644
>> --- a/drivers/media/platform/davinci/vpif_capture.c
>> +++ b/drivers/media/platform/davinci/vpif_capture.c
>> @@ -26,6 +26,8 @@
>> #include <linux/slab.h>
>>
>> #include <media/v4l2-ioctl.h>
>> +#include <media/v4l2-of.h>
>> +#include <media/i2c/tvp514x.h>
>
> Do you need this header?
>
Yes, based on discussion with Hans, since there is no DT binding for
selecting the input pins of the TVP514x, I have to select it in the
driver, so I need the defines from this header. More on this below...
>>
>> #include "vpif.h"
>> #include "vpif_capture.h"
>> @@ -650,6 +652,10 @@ static int vpif_input_to_subdev(
>>
>> vpif_dbg(2, debug, "vpif_input_to_subdev\n");
>>
>> + if (!chan_cfg)
>> + return -1;
>> + if (input_index >= chan_cfg->input_count)
>> + return -1;
>> subdev_name = chan_cfg->inputs[input_index].subdev_name;
>> if (subdev_name == NULL)
>> return -1;
>> @@ -657,7 +663,7 @@ static int vpif_input_to_subdev(
>> /* loop through the sub device list to get the sub device info */
>> for (i = 0; i < vpif_cfg->subdev_count; i++) {
>> subdev_info = &vpif_cfg->subdev_info[i];
>> - if (!strcmp(subdev_info->name, subdev_name))
>> + if (subdev_info && !strcmp(subdev_info->name, subdev_name))
>> return i;
>> }
>> return -1;
>> @@ -1327,6 +1333,21 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
>> {
>> int i;
>>
>> + for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
>> + struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
>> + const struct device_node *node = _asd->match.of.node;
>> +
>> + if (node == subdev->of_node) {
>> + vpif_obj.sd[i] = subdev;
>> + vpif_obj.config->chan_config->inputs[i].subdev_name =
>> + (char *)subdev->of_node->full_name;
>> + vpif_dbg(2, debug,
>> + "%s: setting input %d subdev_name = %s\n",
>> + __func__, i, subdev->of_node->full_name);
>> + return 0;
>> + }
>> + }
>> +
>> for (i = 0; i < vpif_obj.config->subdev_count; i++)
>> if (!strcmp(vpif_obj.config->subdev_info[i].name,
>> subdev->name)) {
>> @@ -1422,6 +1443,110 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
>> return vpif_probe_complete();
>> }
>>
>> +static struct vpif_capture_config *
>> +vpif_capture_get_pdata(struct platform_device *pdev)
>> +{
>> + struct device_node *endpoint = NULL;
>> + struct v4l2_of_endpoint bus_cfg;
>> + struct vpif_capture_config *pdata;
>> + struct vpif_subdev_info *sdinfo;
>> + struct vpif_capture_chan_config *chan;
>> + unsigned int i;
>> +
>> + dev_dbg(&pdev->dev, "vpif_get_pdata\n");
>> +
>> + if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
>> + return pdev->dev.platform_data;
>> +
>> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
>> + if (!pdata)
>> + return NULL;
>> + pdata->subdev_info =
>> + devm_kzalloc(&pdev->dev, sizeof(*pdata->subdev_info) *
>> + VPIF_CAPTURE_MAX_CHANNELS, GFP_KERNEL);
>> +
>> + if (!pdata->subdev_info)
>> + return NULL;
>> + dev_dbg(&pdev->dev, "%s\n", __func__);
>> +
>> + for (i = 0; ; i++) {
>> + struct device_node *rem;
>> + unsigned int flags;
>> + int err;
>> +
>> + endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
>> + endpoint);
>> + if (!endpoint)
>> + break;
>> +
>> + sdinfo = &pdata->subdev_info[i];
>
> subdev_info[] has got VPIF_CAPTURE_MAX_CHANNELS entries only.
>
Right, I need to make the loop only go for a max of
VPIF_CAPTURE_MAX_CHANNELS iterations.
>> + chan = &pdata->chan_config[i];
>> + chan->inputs = devm_kzalloc(&pdev->dev,
>> + sizeof(*chan->inputs) *
>> + VPIF_DISPLAY_MAX_CHANNELS,
>> + GFP_KERNEL);
>> +
>> + chan->input_count++;
>> + chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
>
> I wonder what's the purpose of using index i on this array as well.
The number of endpoints in DT is the number of input channels configured
(up to a max of VPIF_CAPTURE_MAX_CHANNELS.)
> If you use that to access a corresponding entry in a different array, I'd
> just create a struct that contains the port configuration and the async
> sub-device. The omap3isp driver does that, for instance; see
> isp_of_parse_nodes() in drivers/media/platform/omap3isp/isp.c if you're
> interested. Up to you.
OK, I'll have a look at that driver. The goal here with this series is
just to get this working with DT, but also not break the existing legacy
platform_device support, so I'm trying not to mess with the
driver-interal data structures too much.
>> + chan->inputs[i].input.std = V4L2_STD_ALL;
>> + chan->inputs[i].input.capabilities = V4L2_IN_CAP_STD;
>> +
>> + /* FIXME: need a new property? ch0:composite ch1: s-video */
>> + if (i == 0)
>
> Can you assume that the first endopoint has got a particular kind of input?
> What if it's not connected?
On all the boards I know of (there aren't many using this SoC), it's a
safe assumption.
> If this is a different physical port (not in the meaning another) in the
> device, I'd use the reg property for this. Please see
> Documentation/devicetree/bindings/media/video-interfaces.txt .
My understanding (which is admittedly somewhat fuzzy) of the TVP514x is
that it's not physically a different port. Instead, it's just telling
the TVP514x which pin(s) will be active inputs (and what kind of signal
will be present.)
I'm open to a better way to describe this input select from DT, but
based on what I heard from Hans, there isn't currently a good way to do
that except for in the driver:
(c.f. https://marc.info/?l=linux-arm-kernel&m=147887871615788)
Based on further discussion in that thread, it sounds like there may be
a way forward coming soon, and I'll be glad to switch to that when it
arrives.
>> + chan->inputs[i].input_route = INPUT_CVBS_VI2B;
>> + else
>> + chan->inputs[i].input_route = INPUT_SVIDEO_VI2C_VI1C;
>> + chan->inputs[i].output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC;
>> +
>> + err = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
>> + if (err) {
>> + dev_err(&pdev->dev, "Could not parse the endpoint\n");
>> + goto done;
>> + }
>> + dev_dbg(&pdev->dev, "Endpoint %s, bus_width = %d\n",
>> + endpoint->full_name, bus_cfg.bus.parallel.bus_width);
>> + flags = bus_cfg.bus.parallel.flags;
>> +
>> + if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
>> + chan->vpif_if.hd_pol = 1;
>> +
>> + if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
>> + chan->vpif_if.vd_pol = 1;
>> +
>> + chan->vpif_if.if_type = VPIF_IF_BT656;
>> + rem = of_graph_get_remote_port_parent(endpoint);
>> + if (!rem) {
>> + dev_dbg(&pdev->dev, "Remote device at %s not found\n",
>> + endpoint->full_name);
>> + goto done;
>> + }
>> +
>> + dev_dbg(&pdev->dev, "Remote device %s, %s found\n",
>> + rem->name, rem->full_name);
>> + sdinfo->name = rem->full_name;
>> +
>> + pdata->asd[i] = devm_kzalloc(&pdev->dev,
>> + sizeof(struct v4l2_async_subdev),
>> + GFP_KERNEL);
>
> Do you ensure somewhere that i isn't overrunning the pdata->asd[] array?
> It's got VPIF_CAPTURE_MAX_CHANNELS entries.
Oops, no. That will be fixed by making the outer for loop only iterate
for i = i..VPIF_CAPTURE_MAX_CHANNELS.
Thanks for the review,
Kevin
^ permalink raw reply
* Re: [PATCH v3 3/4] [media] davinci: vpif_capture: get subdevs from DT
From: Kevin Hilman @ 2016-11-23 23:25 UTC (permalink / raw)
To: Sakari Ailus
Cc: linux-media-u79uwXL29TY76Z2rM5mHXA, Hans Verkuil,
devicetree-u79uwXL29TY76Z2rM5mHXA, Sekhar Nori, Axel Haslam,
Bartosz Gołaszewski, Alexandre Bailon, David Lechner
In-Reply-To: <20161123153723.GE16630-S+BSfZ9RZZmRSg0ZkenSGLdO1Tsj/99ntUK59QYPAWc@public.gmane.org>
Hi Sakari,
Sakari Ailus <sakari.ailus-X3B1VOXEql0@public.gmane.org> writes:
> On Tue, Nov 22, 2016 at 07:52:43AM -0800, Kevin Hilman wrote:
>> Allow getting of subdevs from DT ports and endpoints.
>>
>> The _get_pdata() function was larely inspired by (i.e. stolen from)
>
> vpif_capture_get_pdata and "largely"?
Yes, thanks.
>> am437x-vpfe.c
>>
>> Signed-off-by: Kevin Hilman <khilman-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>> ---
>> drivers/media/platform/davinci/vpif_capture.c | 130 +++++++++++++++++++++++++-
>> include/media/davinci/vpif_types.h | 9 +-
>> 2 files changed, 133 insertions(+), 6 deletions(-)
>>
>> diff --git a/drivers/media/platform/davinci/vpif_capture.c b/drivers/media/platform/davinci/vpif_capture.c
>> index 94ee6cf03f02..47a4699157e7 100644
>> --- a/drivers/media/platform/davinci/vpif_capture.c
>> +++ b/drivers/media/platform/davinci/vpif_capture.c
>> @@ -26,6 +26,8 @@
>> #include <linux/slab.h>
>>
>> #include <media/v4l2-ioctl.h>
>> +#include <media/v4l2-of.h>
>> +#include <media/i2c/tvp514x.h>
>
> Do you need this header?
>
Yes, based on discussion with Hans, since there is no DT binding for
selecting the input pins of the TVP514x, I have to select it in the
driver, so I need the defines from this header. More on this below...
>>
>> #include "vpif.h"
>> #include "vpif_capture.h"
>> @@ -650,6 +652,10 @@ static int vpif_input_to_subdev(
>>
>> vpif_dbg(2, debug, "vpif_input_to_subdev\n");
>>
>> + if (!chan_cfg)
>> + return -1;
>> + if (input_index >= chan_cfg->input_count)
>> + return -1;
>> subdev_name = chan_cfg->inputs[input_index].subdev_name;
>> if (subdev_name == NULL)
>> return -1;
>> @@ -657,7 +663,7 @@ static int vpif_input_to_subdev(
>> /* loop through the sub device list to get the sub device info */
>> for (i = 0; i < vpif_cfg->subdev_count; i++) {
>> subdev_info = &vpif_cfg->subdev_info[i];
>> - if (!strcmp(subdev_info->name, subdev_name))
>> + if (subdev_info && !strcmp(subdev_info->name, subdev_name))
>> return i;
>> }
>> return -1;
>> @@ -1327,6 +1333,21 @@ static int vpif_async_bound(struct v4l2_async_notifier *notifier,
>> {
>> int i;
>>
>> + for (i = 0; i < vpif_obj.config->asd_sizes[0]; i++) {
>> + struct v4l2_async_subdev *_asd = vpif_obj.config->asd[i];
>> + const struct device_node *node = _asd->match.of.node;
>> +
>> + if (node == subdev->of_node) {
>> + vpif_obj.sd[i] = subdev;
>> + vpif_obj.config->chan_config->inputs[i].subdev_name =
>> + (char *)subdev->of_node->full_name;
>> + vpif_dbg(2, debug,
>> + "%s: setting input %d subdev_name = %s\n",
>> + __func__, i, subdev->of_node->full_name);
>> + return 0;
>> + }
>> + }
>> +
>> for (i = 0; i < vpif_obj.config->subdev_count; i++)
>> if (!strcmp(vpif_obj.config->subdev_info[i].name,
>> subdev->name)) {
>> @@ -1422,6 +1443,110 @@ static int vpif_async_complete(struct v4l2_async_notifier *notifier)
>> return vpif_probe_complete();
>> }
>>
>> +static struct vpif_capture_config *
>> +vpif_capture_get_pdata(struct platform_device *pdev)
>> +{
>> + struct device_node *endpoint = NULL;
>> + struct v4l2_of_endpoint bus_cfg;
>> + struct vpif_capture_config *pdata;
>> + struct vpif_subdev_info *sdinfo;
>> + struct vpif_capture_chan_config *chan;
>> + unsigned int i;
>> +
>> + dev_dbg(&pdev->dev, "vpif_get_pdata\n");
>> +
>> + if (!IS_ENABLED(CONFIG_OF) || !pdev->dev.of_node)
>> + return pdev->dev.platform_data;
>> +
>> + pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
>> + if (!pdata)
>> + return NULL;
>> + pdata->subdev_info =
>> + devm_kzalloc(&pdev->dev, sizeof(*pdata->subdev_info) *
>> + VPIF_CAPTURE_MAX_CHANNELS, GFP_KERNEL);
>> +
>> + if (!pdata->subdev_info)
>> + return NULL;
>> + dev_dbg(&pdev->dev, "%s\n", __func__);
>> +
>> + for (i = 0; ; i++) {
>> + struct device_node *rem;
>> + unsigned int flags;
>> + int err;
>> +
>> + endpoint = of_graph_get_next_endpoint(pdev->dev.of_node,
>> + endpoint);
>> + if (!endpoint)
>> + break;
>> +
>> + sdinfo = &pdata->subdev_info[i];
>
> subdev_info[] has got VPIF_CAPTURE_MAX_CHANNELS entries only.
>
Right, I need to make the loop only go for a max of
VPIF_CAPTURE_MAX_CHANNELS iterations.
>> + chan = &pdata->chan_config[i];
>> + chan->inputs = devm_kzalloc(&pdev->dev,
>> + sizeof(*chan->inputs) *
>> + VPIF_DISPLAY_MAX_CHANNELS,
>> + GFP_KERNEL);
>> +
>> + chan->input_count++;
>> + chan->inputs[i].input.type = V4L2_INPUT_TYPE_CAMERA;
>
> I wonder what's the purpose of using index i on this array as well.
The number of endpoints in DT is the number of input channels configured
(up to a max of VPIF_CAPTURE_MAX_CHANNELS.)
> If you use that to access a corresponding entry in a different array, I'd
> just create a struct that contains the port configuration and the async
> sub-device. The omap3isp driver does that, for instance; see
> isp_of_parse_nodes() in drivers/media/platform/omap3isp/isp.c if you're
> interested. Up to you.
OK, I'll have a look at that driver. The goal here with this series is
just to get this working with DT, but also not break the existing legacy
platform_device support, so I'm trying not to mess with the
driver-interal data structures too much.
>> + chan->inputs[i].input.std = V4L2_STD_ALL;
>> + chan->inputs[i].input.capabilities = V4L2_IN_CAP_STD;
>> +
>> + /* FIXME: need a new property? ch0:composite ch1: s-video */
>> + if (i == 0)
>
> Can you assume that the first endopoint has got a particular kind of input?
> What if it's not connected?
On all the boards I know of (there aren't many using this SoC), it's a
safe assumption.
> If this is a different physical port (not in the meaning another) in the
> device, I'd use the reg property for this. Please see
> Documentation/devicetree/bindings/media/video-interfaces.txt .
My understanding (which is admittedly somewhat fuzzy) of the TVP514x is
that it's not physically a different port. Instead, it's just telling
the TVP514x which pin(s) will be active inputs (and what kind of signal
will be present.)
I'm open to a better way to describe this input select from DT, but
based on what I heard from Hans, there isn't currently a good way to do
that except for in the driver:
(c.f. https://marc.info/?l=linux-arm-kernel&m=147887871615788)
Based on further discussion in that thread, it sounds like there may be
a way forward coming soon, and I'll be glad to switch to that when it
arrives.
>> + chan->inputs[i].input_route = INPUT_CVBS_VI2B;
>> + else
>> + chan->inputs[i].input_route = INPUT_SVIDEO_VI2C_VI1C;
>> + chan->inputs[i].output_route = OUTPUT_10BIT_422_EMBEDDED_SYNC;
>> +
>> + err = v4l2_of_parse_endpoint(endpoint, &bus_cfg);
>> + if (err) {
>> + dev_err(&pdev->dev, "Could not parse the endpoint\n");
>> + goto done;
>> + }
>> + dev_dbg(&pdev->dev, "Endpoint %s, bus_width = %d\n",
>> + endpoint->full_name, bus_cfg.bus.parallel.bus_width);
>> + flags = bus_cfg.bus.parallel.flags;
>> +
>> + if (flags & V4L2_MBUS_HSYNC_ACTIVE_HIGH)
>> + chan->vpif_if.hd_pol = 1;
>> +
>> + if (flags & V4L2_MBUS_VSYNC_ACTIVE_HIGH)
>> + chan->vpif_if.vd_pol = 1;
>> +
>> + chan->vpif_if.if_type = VPIF_IF_BT656;
>> + rem = of_graph_get_remote_port_parent(endpoint);
>> + if (!rem) {
>> + dev_dbg(&pdev->dev, "Remote device at %s not found\n",
>> + endpoint->full_name);
>> + goto done;
>> + }
>> +
>> + dev_dbg(&pdev->dev, "Remote device %s, %s found\n",
>> + rem->name, rem->full_name);
>> + sdinfo->name = rem->full_name;
>> +
>> + pdata->asd[i] = devm_kzalloc(&pdev->dev,
>> + sizeof(struct v4l2_async_subdev),
>> + GFP_KERNEL);
>
> Do you ensure somewhere that i isn't overrunning the pdata->asd[] array?
> It's got VPIF_CAPTURE_MAX_CHANNELS entries.
Oops, no. That will be fixed by making the outer for loop only iterate
for i = i..VPIF_CAPTURE_MAX_CHANNELS.
Thanks for the review,
Kevin
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH V5 3/3] ARM64 LPC: LPC driver implementation on Hip06
From: Arnd Bergmann @ 2016-11-23 23:23 UTC (permalink / raw)
To: linux-arm-kernel
Cc: mark.rutland@arm.com, Gabriele Paoloni, benh@kernel.crashing.org,
liviu.dudau@arm.com, Linuxarm, lorenzo.pieralisi@arm.com,
xuwei (O), Jason Gunthorpe, T homas Petazzoni,
linux-serial@vger.kernel.org, catalin.marinas@arm.com,
devicetree@vger.kernel.org, minyard@acm.org, will.deacon@arm.com,
John Garry, zourongrong@gmail.com, robh+dt@kernel.org,
bhelgaas@go og le.com, kantyzc
In-Reply-To: <2168980.T3HadihU3R@wuerfel>
On Wednesday, November 23, 2016 6:07:11 PM CET Arnd Bergmann wrote:
> On Wednesday, November 23, 2016 3:22:33 PM CET Gabriele Paoloni wrote:
> > From: Arnd Bergmann [mailto:arnd@arndb.de]
> > > On Friday, November 18, 2016 5:03:11 PM CET Gabriele Paoloni wrote:
>
> Please don't proliferate the use of
> pci_pio_to_address/pci_address_to_pio here, computing the physical
> address from the logical address is trivial, you just need to
> subtract the start of the range that you already use when matching
> the port number range.
>
> The only thing we need here is to make of_address_to_resource()
> return the correct logical port number that was registered for
> a given host device when asked to translate an address that
> does not have a CPU address associated with it.
Ok, I admit this was a little harder than I expected, but see below
for a rough outline of how I think it can be done.
This makes it possible to translate bus specific I/O port numbers
from device nodes into Linux port numbers, and gives a way to register
them. We could take this further and completely remove pci_pio_to_address
and pci_address_to_pio if we make the I/O port translation always
go through the io_range list, looking up up the hostbridge by fwnode,
but we don't have to do that now.
The patch is completely untested and probably buggy, it just seemed
easier to put out a prototype than to keep going in circles with the
discussion.
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index bf601d4df8cf..6cadf0501bb0 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -730,7 +730,8 @@ static void acpi_pci_root_validate_resources(struct device *dev,
}
}
-static void acpi_pci_root_remap_iospace(struct resource_entry *entry)
+static void acpi_pci_root_remap_iospace(struct fwnode_handle *node,
+ struct resource_entry *entry)
{
#ifdef PCI_IOBASE
struct resource *res = entry->res;
@@ -739,11 +740,7 @@ static void acpi_pci_root_remap_iospace(struct resource_entry *entry)
resource_size_t length = resource_size(res);
unsigned long port;
- if (pci_register_io_range(cpu_addr, length))
- goto err;
-
- port = pci_address_to_pio(cpu_addr);
- if (port == (unsigned long)-1)
+ if (pci_register_io_range(node, cpu_addr, length, &port))
goto err;
res->start = port;
@@ -781,7 +778,8 @@ int acpi_pci_probe_root_resources(struct acpi_pci_root_info *info)
else {
resource_list_for_each_entry_safe(entry, tmp, list) {
if (entry->res->flags & IORESOURCE_IO)
- acpi_pci_root_remap_iospace(entry);
+ acpi_pci_root_remap_iospace(&device->fwnode,
+ entry);
if (entry->res->flags & IORESOURCE_DISABLED)
resource_list_destroy_entry(entry);
diff --git a/drivers/block/nbd.c b/drivers/block/nbd.c
index a50025a3777f..df96955a43f8 100644
--- a/drivers/block/nbd.c
+++ b/drivers/block/nbd.c
@@ -760,8 +760,10 @@ static int __nbd_ioctl(struct block_device *bdev, struct nbd_device *nbd,
set_bit(NBD_RUNNING, &nbd->runtime_flags);
blk_mq_update_nr_hw_queues(&nbd->tag_set, nbd->num_connections);
args = kcalloc(num_connections, sizeof(*args), GFP_KERNEL);
- if (!args)
+ if (!args) {
+ error = -ENOMEM;
goto out_err;
+ }
nbd->task_recv = current;
mutex_unlock(&nbd->config_lock);
diff --git a/drivers/of/address.c b/drivers/of/address.c
index 02b2903fe9d2..5decaba96eed 100644
--- a/drivers/of/address.c
+++ b/drivers/of/address.c
@@ -2,6 +2,7 @@
#define pr_fmt(fmt) "OF: " fmt
#include <linux/device.h>
+#include <linux/fwnode.h>
#include <linux/io.h>
#include <linux/ioport.h>
#include <linux/module.h>
@@ -323,14 +324,9 @@ int of_pci_range_to_resource(struct of_pci_range *range,
if (res->flags & IORESOURCE_IO) {
unsigned long port;
- err = pci_register_io_range(range->cpu_addr, range->size);
+ err = pci_register_io_range(&np->fwnode, range->cpu_addr, range->size, &port);
if (err)
goto invalid_range;
- port = pci_address_to_pio(range->cpu_addr);
- if (port == (unsigned long)-1) {
- err = -EINVAL;
- goto invalid_range;
- }
res->start = port;
} else {
if ((sizeof(resource_size_t) < 8) &&
@@ -479,7 +475,7 @@ static int of_empty_ranges_quirk(struct device_node *np)
return false;
}
-static int of_translate_one(struct device_node *parent, struct of_bus *bus,
+static u64 of_translate_one(struct device_node *parent, struct of_bus *bus,
struct of_bus *pbus, __be32 *addr,
int na, int ns, int pna, const char *rprop)
{
@@ -507,7 +503,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
ranges = of_get_property(parent, rprop, &rlen);
if (ranges == NULL && !of_empty_ranges_quirk(parent)) {
pr_debug("no ranges; cannot translate\n");
- return 1;
+ return OF_BAD_ADDR;
}
if (ranges == NULL || rlen == 0) {
offset = of_read_number(addr, na);
@@ -528,7 +524,7 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
}
if (offset == OF_BAD_ADDR) {
pr_debug("not found !\n");
- return 1;
+ return offset;
}
memcpy(addr, ranges + na, 4 * pna);
@@ -537,7 +533,10 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
pr_debug("with offset: %llx\n", (unsigned long long)offset);
/* Translate it into parent bus space */
- return pbus->translate(addr, offset, pna);
+ if (pbus->translate(addr, offset, pna))
+ return OF_BAD_ADDR;
+
+ return offset;
}
/*
@@ -549,9 +548,14 @@ static int of_translate_one(struct device_node *parent, struct of_bus *bus,
* that translation is impossible (that is we are not dealing with a value
* that can be mapped to a cpu physical address). This is not really specified
* that way, but this is traditionally the way IBM at least do things
+ *
+ * Whenever the translation fails, the *host pointer will be set to the
+ * device that lacks a tranlation, and the return code is relative to
+ * that node.
*/
static u64 __of_translate_address(struct device_node *dev,
- const __be32 *in_addr, const char *rprop)
+ const __be32 *in_addr, const char *rprop,
+ struct device_node **host)
{
struct device_node *parent = NULL;
struct of_bus *bus, *pbus;
@@ -564,6 +568,7 @@ static u64 __of_translate_address(struct device_node *dev,
/* Increase refcount at current level */
of_node_get(dev);
+ *host = NULL;
/* Get parent & match bus type */
parent = of_get_parent(dev);
if (parent == NULL)
@@ -600,8 +605,9 @@ static u64 __of_translate_address(struct device_node *dev,
pbus = of_match_bus(parent);
pbus->count_cells(dev, &pna, &pns);
if (!OF_CHECK_COUNTS(pna, pns)) {
- pr_err("Bad cell count for %s\n",
- of_node_full_name(dev));
+ pr_debug("Bad cell count for %s\n",
+ of_node_full_name(dev));
+ *host = of_node_get(parent);
break;
}
@@ -609,7 +615,9 @@ static u64 __of_translate_address(struct device_node *dev,
pbus->name, pna, pns, of_node_full_name(parent));
/* Apply bus translation */
- if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop))
+ result = of_translate_one(dev, bus, pbus, addr, na, ns,
+ pna, rprop);
+ if (result == OF_BAD_ADDR)
break;
/* Complete the move up one level */
@@ -628,13 +636,32 @@ static u64 __of_translate_address(struct device_node *dev,
u64 of_translate_address(struct device_node *dev, const __be32 *in_addr)
{
- return __of_translate_address(dev, in_addr, "ranges");
+ struct device_node *host;
+ u64 ret;
+
+ ret = __of_translate_address(dev, in_addr, "ranges", &host);
+ if (host) {
+ of_node_put(host);
+ return OF_BAD_ADDR;
+ }
+
+ return ret;
}
EXPORT_SYMBOL(of_translate_address);
u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr)
{
- return __of_translate_address(dev, in_addr, "dma-ranges");
+ struct device_node *host;
+ u64 ret;
+
+ ret = __of_translate_address(dev, in_addr, "dma-ranges", &host);
+
+ if (host) {
+ of_node_put(host);
+ return OF_BAD_ADDR;
+ }
+
+ return ret;
}
EXPORT_SYMBOL(of_translate_dma_address);
@@ -676,29 +703,48 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size,
}
EXPORT_SYMBOL(of_get_address);
+extern unsigned long extio_translate(struct fwnode_handle *node, unsigned long offset);
+
+u64 of_translate_ioport(struct device_node *dev, const __be32 *in_addr)
+{
+ u64 taddr;
+ unsigned long port;
+ struct device_node *host;
+
+ taddr = __of_translate_address(dev, in_addr, "ranges", &host);
+ if (host) {
+ /* host specific port access */
+ port = extio_translate(&host->fwnode, taddr);
+ of_node_put(host);
+ } else {
+ /* memory mapped I/O range */
+ port = pci_address_to_pio(taddr);
+ if (port == (unsigned long)-1)
+ return OF_BAD_ADDR;
+ }
+
+ return port;
+}
+
static int __of_address_to_resource(struct device_node *dev,
const __be32 *addrp, u64 size, unsigned int flags,
const char *name, struct resource *r)
{
u64 taddr;
- if ((flags & (IORESOURCE_IO | IORESOURCE_MEM)) == 0)
+ if (flags & IORESOURCE_MEM)
+ taddr = of_translate_address(dev, addrp);
+ else if (flags & IORESOURCE_IO)
+ taddr = of_translate_ioport(dev, addrp);
+ else
return -EINVAL;
- taddr = of_translate_address(dev, addrp);
+
if (taddr == OF_BAD_ADDR)
return -EINVAL;
memset(r, 0, sizeof(struct resource));
- if (flags & IORESOURCE_IO) {
- unsigned long port;
- port = pci_address_to_pio(taddr);
- if (port == (unsigned long)-1)
- return -EINVAL;
- r->start = port;
- r->end = port + size - 1;
- } else {
- r->start = taddr;
- r->end = taddr + size - 1;
- }
+
+ r->start = taddr;
+ r->end = taddr + size - 1;
r->flags = flags;
r->name = name ? name : dev->full_name;
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index eda6a7cf0e54..320ab9fbf6af 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -3249,6 +3249,7 @@ EXPORT_SYMBOL(pci_request_regions_exclusive);
#ifdef PCI_IOBASE
struct io_range {
struct list_head list;
+ struct fwnode_handle *node;
phys_addr_t start;
resource_size_t size;
};
@@ -3257,11 +3258,14 @@ static LIST_HEAD(io_range_list);
static DEFINE_SPINLOCK(io_range_lock);
#endif
+#define IO_RANGE_IOEXT (resource_size_t)(-1ull)
+
/*
* Record the PCI IO range (expressed as CPU physical address + size).
* Return a negative value if an error has occured, zero otherwise
*/
-int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
+int __weak pci_register_io_range(struct fwnode_handle *node, phys_addr_t addr,
+ resource_size_t size, unsigned long *port)
{
int err = 0;
@@ -3272,7 +3276,12 @@ int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
/* check if the range hasn't been previously recorded */
spin_lock(&io_range_lock);
list_for_each_entry(range, &io_range_list, list) {
- if (addr >= range->start && addr + size <= range->start + size) {
+ if (node == range->node)
+ goto end_register;
+
+ if (addr != IO_RANGE_IOEXT &&
+ addr >= range->start &&
+ addr + size <= range->start + size) {
/* range already registered, bail out */
goto end_register;
}
@@ -3298,6 +3307,7 @@ int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
goto end_register;
}
+ range->node = node;
range->start = addr;
range->size = size;
@@ -3305,11 +3315,26 @@ int __weak pci_register_io_range(phys_addr_t addr, resource_size_t size)
end_register:
spin_unlock(&io_range_lock);
+
+ *port = allocated_size;
+#else
+ /*
+ * powerpc and microblaze have their own registration,
+ * just look up the value here
+ */
+ *port = pci_address_to_pio(addr);
#endif
return err;
}
+#ifdef CONFIG_IOEXT
+int ioext_register_io_range
+{
+ return pci_register_io_range(node, IO_RANGE_IOEXT, size, port);
+}
+#endif
+
phys_addr_t pci_pio_to_address(unsigned long pio)
{
phys_addr_t address = (phys_addr_t)OF_BAD_ADDR;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 6bd94a803e8f..b7a8fa3da3ca 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1192,7 +1192,8 @@ int __must_check pci_bus_alloc_resource(struct pci_bus *bus,
void *alignf_data);
-int pci_register_io_range(phys_addr_t addr, resource_size_t size);
+int pci_register_io_range(struct fwnode_handle *node, phys_addr_t addr,
+ resource_size_t size, unsigned long *port);
unsigned long pci_address_to_pio(phys_addr_t addr);
phys_addr_t pci_pio_to_address(unsigned long pio);
int pci_remap_iospace(const struct resource *res, phys_addr_t phys_addr);
^ permalink raw reply related
* Re: [PATCH v7] PCI: qcom: add support to msm8996 PCIe controller
From: Bjorn Helgaas @ 2016-11-23 23:08 UTC (permalink / raw)
To: Srinivas Kandagatla
Cc: svarbanov-NEYub+7Iv8PQT0dZR+AlfA,
linux-pci-u79uwXL29TY76Z2rM5mHXA, bhelgaas-hpIqsD4AKlfQT0dZR+AlfA,
robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
linux-arm-msm-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <1479811409-22375-1-git-send-email-srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On Tue, Nov 22, 2016 at 10:43:29AM +0000, Srinivas Kandagatla wrote:
> This patch adds support to msm8996/apq8096 PCIe, MSM8996 supports
> Gen 1/2, One lane, 3 PCIe root-complex with support to MSI and
> legacy interrupts and it conforms to PCI Express Base 2.1 specification.
>
> This patch adds post_init callback to qcom_pcie_ops, as this is PCIe
> pipe clocks are only setup after the phy is powered on.
> It also adds ltssm_enable callback as it is very much different to other
> supported SOCs in the driver.
>
> Signed-off-by: Srinivas Kandagatla <srinivas.kandagatla-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> Acked-by: Stanimir Varbanov <svarbanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
Applied to pci/host-qcom for v4.10, thanks!
> ---
> Changes since v5/v6:
> - No code changes.
> - s/pcie/PCIe in change log based on Rob's comments.
> - Removed DT example for 8996 as requested by Rob.
>
> .../devicetree/bindings/pci/qcom,pcie.txt | 14 +-
> drivers/pci/host/pcie-qcom.c | 175 ++++++++++++++++++++-
> 2 files changed, 183 insertions(+), 6 deletions(-)
>
> diff --git a/Documentation/devicetree/bindings/pci/qcom,pcie.txt b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
> index 4059a6f..15ced03 100644
> --- a/Documentation/devicetree/bindings/pci/qcom,pcie.txt
> +++ b/Documentation/devicetree/bindings/pci/qcom,pcie.txt
> @@ -7,6 +7,7 @@
> - "qcom,pcie-ipq8064" for ipq8064
> - "qcom,pcie-apq8064" for apq8064
> - "qcom,pcie-apq8084" for apq8084
> + - "qcom,pcie-msm8996" for msm8996 or apq8096
>
> - reg:
> Usage: required
> @@ -92,6 +93,17 @@
> - "aux" Auxiliary (AUX) clock
> - "bus_master" Master AXI clock
> - "bus_slave" Slave AXI clock
> +
> +- clock-names:
> + Usage: required for msm8996/apq8096
> + Value type: <stringlist>
> + Definition: Should contain the following entries
> + - "pipe" Pipe Clock driving internal logic.
> + - "aux" Auxiliary (AUX) clock.
> + - "cfg" Configuration clk.
> + - "bus_master" Master AXI clock.
> + - "bus_slave" Slave AXI clock.
> +
> - resets:
> Usage: required
> Value type: <prop-encoded-array>
> @@ -115,7 +127,7 @@
> - "core" Core reset
>
> - power-domains:
> - Usage: required for apq8084
> + Usage: required for apq8084 and msm8996/apq8096
> Value type: <prop-encoded-array>
> Definition: A phandle and power domain specifier pair to the
> power domain which is responsible for collapsing
> diff --git a/drivers/pci/host/pcie-qcom.c b/drivers/pci/host/pcie-qcom.c
> index 3593640..25c5556 100644
> --- a/drivers/pci/host/pcie-qcom.c
> +++ b/drivers/pci/host/pcie-qcom.c
> @@ -36,11 +36,17 @@
>
> #include "pcie-designware.h"
>
> +#define PCIE20_PARF_SYS_CTRL 0x00
> #define PCIE20_PARF_PHY_CTRL 0x40
> #define PCIE20_PARF_PHY_REFCLK 0x4C
> #define PCIE20_PARF_DBI_BASE_ADDR 0x168
> #define PCIE20_PARF_SLV_ADDR_SPACE_SIZE 0x16c
> +#define PCIE20_PARF_MHI_CLOCK_RESET_CTRL 0x174
> #define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT 0x178
> +#define PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2 0x1A8
> +#define PCIE20_PARF_LTSSM 0x1B0
> +#define PCIE20_PARF_SID_OFFSET 0x234
> +#define PCIE20_PARF_BDF_TRANSLATE_CFG 0x24C
>
> #define PCIE20_ELBI_SYS_CTRL 0x04
> #define PCIE20_ELBI_SYS_CTRL_LT_ENABLE BIT(0)
> @@ -72,9 +78,18 @@ struct qcom_pcie_resources_v1 {
> struct regulator *vdda;
> };
>
> +struct qcom_pcie_resources_v2 {
> + struct clk *aux_clk;
> + struct clk *master_clk;
> + struct clk *slave_clk;
> + struct clk *cfg_clk;
> + struct clk *pipe_clk;
> +};
> +
> union qcom_pcie_resources {
> struct qcom_pcie_resources_v0 v0;
> struct qcom_pcie_resources_v1 v1;
> + struct qcom_pcie_resources_v2 v2;
> };
>
> struct qcom_pcie;
> @@ -82,7 +97,9 @@ struct qcom_pcie;
> struct qcom_pcie_ops {
> int (*get_resources)(struct qcom_pcie *pcie);
> int (*init)(struct qcom_pcie *pcie);
> + int (*post_init)(struct qcom_pcie *pcie);
> void (*deinit)(struct qcom_pcie *pcie);
> + void (*ltssm_enable)(struct qcom_pcie *pcie);
> };
>
> struct qcom_pcie {
> @@ -116,17 +133,33 @@ static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
> return dw_handle_msi_irq(pp);
> }
>
> -static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
> +static void qcom_pcie_v0_v1_ltssm_enable(struct qcom_pcie *pcie)
> {
> u32 val;
> -
> - if (dw_pcie_link_up(&pcie->pp))
> - return 0;
> -
> /* enable link training */
> val = readl(pcie->elbi + PCIE20_ELBI_SYS_CTRL);
> val |= PCIE20_ELBI_SYS_CTRL_LT_ENABLE;
> writel(val, pcie->elbi + PCIE20_ELBI_SYS_CTRL);
> +}
> +
> +static void qcom_pcie_v2_ltssm_enable(struct qcom_pcie *pcie)
> +{
> + u32 val;
> + /* enable link training */
> + val = readl(pcie->parf + PCIE20_PARF_LTSSM);
> + val |= BIT(8);
> + writel(val, pcie->parf + PCIE20_PARF_LTSSM);
> +}
> +
> +static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
> +{
> +
> + if (dw_pcie_link_up(&pcie->pp))
> + return 0;
> +
> + /* Enable Link Training state machine */
> + if (pcie->ops->ltssm_enable)
> + pcie->ops->ltssm_enable(pcie);
>
> return dw_pcie_wait_for_link(&pcie->pp);
> }
> @@ -421,6 +454,113 @@ static int qcom_pcie_init_v1(struct qcom_pcie *pcie)
> return ret;
> }
>
> +static int qcom_pcie_get_resources_v2(struct qcom_pcie *pcie)
> +{
> + struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
> + struct device *dev = pcie->pp.dev;
> +
> + res->aux_clk = devm_clk_get(dev, "aux");
> + if (IS_ERR(res->aux_clk))
> + return PTR_ERR(res->aux_clk);
> +
> + res->cfg_clk = devm_clk_get(dev, "cfg");
> + if (IS_ERR(res->cfg_clk))
> + return PTR_ERR(res->cfg_clk);
> +
> + res->master_clk = devm_clk_get(dev, "bus_master");
> + if (IS_ERR(res->master_clk))
> + return PTR_ERR(res->master_clk);
> +
> + res->slave_clk = devm_clk_get(dev, "bus_slave");
> + if (IS_ERR(res->slave_clk))
> + return PTR_ERR(res->slave_clk);
> +
> + res->pipe_clk = devm_clk_get(dev, "pipe");
> + if (IS_ERR(res->pipe_clk))
> + return PTR_ERR(res->pipe_clk);
> +
> + return 0;
> +}
> +
> +static int qcom_pcie_init_v2(struct qcom_pcie *pcie)
> +{
> + struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
> + struct device *dev = pcie->pp.dev;
> + u32 val;
> + int ret;
> +
> + ret = clk_prepare_enable(res->aux_clk);
> + if (ret) {
> + dev_err(dev, "cannot prepare/enable aux clock\n");
> + return ret;
> + }
> +
> + ret = clk_prepare_enable(res->cfg_clk);
> + if (ret) {
> + dev_err(dev, "cannot prepare/enable cfg clock\n");
> + goto err_cfg_clk;
> + }
> +
> + ret = clk_prepare_enable(res->master_clk);
> + if (ret) {
> + dev_err(dev, "cannot prepare/enable master clock\n");
> + goto err_master_clk;
> + }
> +
> + ret = clk_prepare_enable(res->slave_clk);
> + if (ret) {
> + dev_err(dev, "cannot prepare/enable slave clock\n");
> + goto err_slave_clk;
> + }
> +
> + /* enable PCIe clocks and resets */
> + val = readl(pcie->parf + PCIE20_PARF_PHY_CTRL);
> + val &= ~BIT(0);
> + writel(val, pcie->parf + PCIE20_PARF_PHY_CTRL);
> +
> + /* change DBI base address */
> + writel(0, pcie->parf + PCIE20_PARF_DBI_BASE_ADDR);
> +
> + /* MAC PHY_POWERDOWN MUX DISABLE */
> + val = readl(pcie->parf + PCIE20_PARF_SYS_CTRL);
> + val &= ~BIT(29);
> + writel(val, pcie->parf + PCIE20_PARF_SYS_CTRL);
> +
> + val = readl(pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> + val |= BIT(4);
> + writel(val, pcie->parf + PCIE20_PARF_MHI_CLOCK_RESET_CTRL);
> +
> + val = readl(pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> + val |= BIT(31);
> + writel(val, pcie->parf + PCIE20_PARF_AXI_MSTR_WR_ADDR_HALT_V2);
> +
> + return 0;
> +
> +err_slave_clk:
> + clk_disable_unprepare(res->master_clk);
> +err_master_clk:
> + clk_disable_unprepare(res->cfg_clk);
> +err_cfg_clk:
> + clk_disable_unprepare(res->aux_clk);
> +
> + return ret;
> +}
> +
> +static int qcom_pcie_post_init_v2(struct qcom_pcie *pcie)
> +{
> + struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
> + struct device *dev = pcie->pp.dev;
> + int ret;
> +
> + ret = clk_prepare_enable(res->pipe_clk);
> + if (ret) {
> + dev_err(dev, "cannot prepare/enable pipe clock\n");
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static int qcom_pcie_link_up(struct pcie_port *pp)
> {
> struct qcom_pcie *pcie = to_qcom_pcie(pp);
> @@ -429,6 +569,17 @@ static int qcom_pcie_link_up(struct pcie_port *pp)
> return !!(val & PCI_EXP_LNKSTA_DLLLA);
> }
>
> +static void qcom_pcie_deinit_v2(struct qcom_pcie *pcie)
> +{
> + struct qcom_pcie_resources_v2 *res = &pcie->res.v2;
> +
> + clk_disable_unprepare(res->pipe_clk);
> + clk_disable_unprepare(res->slave_clk);
> + clk_disable_unprepare(res->master_clk);
> + clk_disable_unprepare(res->cfg_clk);
> + clk_disable_unprepare(res->aux_clk);
> +}
> +
> static void qcom_pcie_host_init(struct pcie_port *pp)
> {
> struct qcom_pcie *pcie = to_qcom_pcie(pp);
> @@ -444,6 +595,9 @@ static void qcom_pcie_host_init(struct pcie_port *pp)
> if (ret)
> goto err_deinit;
>
> + if (pcie->ops->post_init)
> + pcie->ops->post_init(pcie);
> +
> dw_pcie_setup_rc(pp);
>
> if (IS_ENABLED(CONFIG_PCI_MSI))
> @@ -487,12 +641,22 @@ static const struct qcom_pcie_ops ops_v0 = {
> .get_resources = qcom_pcie_get_resources_v0,
> .init = qcom_pcie_init_v0,
> .deinit = qcom_pcie_deinit_v0,
> + .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable,
> };
>
> static const struct qcom_pcie_ops ops_v1 = {
> .get_resources = qcom_pcie_get_resources_v1,
> .init = qcom_pcie_init_v1,
> .deinit = qcom_pcie_deinit_v1,
> + .ltssm_enable = qcom_pcie_v0_v1_ltssm_enable,
> +};
> +
> +static const struct qcom_pcie_ops ops_v2 = {
> + .get_resources = qcom_pcie_get_resources_v2,
> + .init = qcom_pcie_init_v2,
> + .post_init = qcom_pcie_post_init_v2,
> + .deinit = qcom_pcie_deinit_v2,
> + .ltssm_enable = qcom_pcie_v2_ltssm_enable,
> };
>
> static int qcom_pcie_probe(struct platform_device *pdev)
> @@ -572,6 +736,7 @@ static const struct of_device_id qcom_pcie_match[] = {
> { .compatible = "qcom,pcie-ipq8064", .data = &ops_v0 },
> { .compatible = "qcom,pcie-apq8064", .data = &ops_v0 },
> { .compatible = "qcom,pcie-apq8084", .data = &ops_v1 },
> + { .compatible = "qcom,pcie-msm8996", .data = &ops_v2 },
> { }
> };
>
> --
> 2.10.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/4] clocksource/drivers/arm_arch_timer: Don't assume clock runs in suspend
From: Rob Herring @ 2016-11-23 23:07 UTC (permalink / raw)
To: Daniel Lezcano
Cc: tglx-hfZtesqFncYOwBW4kG4KsQ, linux-kernel-u79uwXL29TY76Z2rM5mHXA,
Brian Norris, Marc Zyngier, Mark Rutland, Will Deacon,
Douglas Anderson, Scott Wood,
open list:OPEN FIRMWARE AND FLATTENED DEVICE TREE BINDINGS,
moderated list:ARM ARCHITECTED TIMER DRIVER
In-Reply-To: <1479807866-6957-1-git-send-email-daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
On Tue, Nov 22, 2016 at 10:44:21AM +0100, Daniel Lezcano wrote:
> From: Brian Norris <briannorris-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
>
> The ARM specifies that the system counter "must be implemented in an
> always-on power domain," and so we try to use the counter as a source of
> timekeeping across suspend/resume. Unfortunately, some SoCs (e.g.,
> Rockchip's RK3399) do not keep the counter ticking properly when
> switched from their high-power clock to the lower-power clock used in
> system suspend. Support this quirk by adding a new device tree property.
>
> Signed-off-by: Brian Norris <briannorris-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> Reviewed-by: Douglas Anderson <dianders-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org>
> Acked-by: Marc Zyngier <marc.zyngier-5wv7dgnIgG8@public.gmane.org>
> Signed-off-by: Daniel Lezcano <daniel.lezcano-QSEj5FYQhm4dnm+yROfE0A@public.gmane.org>
> ---
> Documentation/devicetree/bindings/arm/arch_timer.txt | 5 +++++
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
> drivers/clocksource/arm_arch_timer.c | 9 ++++++++-
> 2 files changed, 13 insertions(+), 1 deletion(-)
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 4/6] dt-bindings: change hi6220-reset.txt according to reset-hi6220.c
From: Rob Herring @ 2016-11-23 23:06 UTC (permalink / raw)
To: Arnd Bergmann
Cc: Zhangfei Gao, Philipp Zabel,
haojian.zhuang-QSEj5FYQhm4dnm+yROfE0A,
xuwei5-C8/M+/jPZTeaMJb+Lgu22Q, Chen Feng, Xinliang Liu, Xia Qing,
Jiancheng Xue, linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <2314383.qiZ3Cq7QsP@wuerfel>
On Tue, Nov 22, 2016 at 09:48:32AM +0100, Arnd Bergmann wrote:
> On Tuesday, November 22, 2016 3:49:19 PM CET Zhangfei Gao wrote:
> > Required properties:
> > - compatible: should be one of the following:
> > - - "hisilicon,hi6220-sysctrl", "syscon" : For peripheral reset controller.
> > - - "hisilicon,hi6220-mediactrl", "syscon" : For media reset controller.
> > -- reg: should be register base and length as documented in the
> > - datasheet
> > + - "hisilicon,hi6220-reset-sysctrl" : For peripheral reset controller.
> > + - "hisilicon,hi6220-reset-mediactrl" : For media reset controller.
> > +- hisi,rst-syscon: phandle of the reset's syscon.
> > - #reset-cells: 1, see below
> >
>
> Please keep the old strings around for compatibility.
Why are these even changing? The commit message should say why.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ARM: dts: imx7d: fix LCDIF clock assignment
From: Fabio Estevam @ 2016-11-23 23:02 UTC (permalink / raw)
To: Stefan Agner
Cc: Mark Rutland, devicetree@vger.kernel.org, Liu Ying, linux-kernel,
robh+dt@kernel.org, Peter Chen, Sascha Hauer, Fabio Estevam,
Shawn Guo, linux-arm-kernel@lists.infradead.org
In-Reply-To: <20161123004204.10851-1-stefan@agner.ch>
On Tue, Nov 22, 2016 at 10:42 PM, Stefan Agner <stefan@agner.ch> wrote:
> The eLCDIF IP of the i.MX 7 SoC knows multiple clocks and lists them
> separately:
>
> Clock Clock Root Description
> apb_clk MAIN_AXI_CLK_ROOT AXI clock
> pix_clk LCDIF_PIXEL_CLK_ROOT Pixel clock
> ipg_clk_s MAIN_AXI_CLK_ROOT Peripheral access clock
>
> All of them are switched by a single gate, which is part of the
> IMX7D_LCDIF_PIXEL_ROOT_CLK clock. Hence using that clock also for
> the AXI bus clock (clock-name "axi") makes sure the gate gets
> enabled when accessing registers.
>
> There seem to be no separate AXI display clock, and the clock is
> optional. Hence remove the dummy clock.
>
> This fixes kernel freezes when starting the X-Server (which
> disables/re-enables the display controller).
>
> Signed-off-by: Stefan Agner <stefan@agner.ch>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
^ permalink raw reply
* Re: [PATCH v2] ARM: dts: AM571x-IDK Initial Support
From: Rob Herring @ 2016-11-23 23:02 UTC (permalink / raw)
To: Lokesh Vutla
Cc: Nishanth Menon, devicetree, spatton, Tony Lindgren, Dave Gerlach,
Sekhar Nori, Tero Kristo, Linux OMAP Mailing List,
Linux ARM Mailing List
In-Reply-To: <20161122041732.8385-1-lokeshvutla@ti.com>
On Tue, Nov 22, 2016 at 09:47:32AM +0530, Lokesh Vutla wrote:
> From: Schuyler Patton <spatton@ti.com>
>
> The AM571x-IDK board is a board based on TI's AM5718 SOC
> which has a single core 1.5GHz A15 processor. This board is a
> development platform for the Industrial market with:
> - 1GB of DDR3L
> - Dual 1Gbps Ethernet
> - HDMI,
> - PRU-ICSS
> - uSD
> - 16GB eMMC
> - CAN
> - RS-485
> - PCIe
> - USB3.0
> - Video Input Port
> - Industrial IO port and expansion connector
>
> The link to the data sheet and TRM can be found here:
>
> http://www.ti.com/product/AM5718
>
> Initial support is only for basic peripherals.
>
> Signed-off-by: Schuyler Patton <spatton@ti.com>
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Signed-off-by: Dave Gerlach <d-gerlach@ti.com>
> Signed-off-by: Lokesh Vutla <lokeshvutla@ti.com>
> ---
> Cahnges since v1:
> - Dropped "ti,dra722", and "ti,dra72" from compatibles
> - Fixes few node names as suggested by Rob.
> Logs: http://pastebin.ubuntu.com/23515001/
>
> .../devicetree/bindings/arm/omap/omap.txt | 3 +
> arch/arm/boot/dts/Makefile | 1 +
> arch/arm/boot/dts/am571x-idk.dts | 81 ++++++++++++++++++++++
> 3 files changed, 85 insertions(+)
> create mode 100644 arch/arm/boot/dts/am571x-idk.dts
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH] ARM: dts: imx6q-cm-fx6: enable S/PDIF support
From: Fabio Estevam @ 2016-11-23 23:01 UTC (permalink / raw)
To: Christopher Spinrath
Cc: Mark Rutland, devicetree@vger.kernel.org,
Russell King - ARM Linux, robh+dt@kernel.org, Igor Grinberg,
Sascha Hauer, Fabio Estevam, Shawn Guo,
linux-arm-kernel@lists.infradead.org
In-Reply-To: <5da612fbab7a4064993790702550fa77@rwthex-s1-b.rwth-ad.de>
On Tue, Nov 22, 2016 at 10:07 PM, <christopher.spinrath@rwth-aachen.de> wrote:
> From: Christopher Spinrath <christopher.spinrath@rwth-aachen.de>
>
> Enable the S/PDIF transceiver present on the cm-fx6 module.
>
> Signed-off-by: Christopher Spinrath <christopher.spinrath@rwth-aachen.de>
Reviewed-by: Fabio Estevam <fabio.estevam@nxp.com>
^ permalink raw reply
* Re: [PATCH v4 1/2] Documentation: dt: reset: Add TI SCI reset binding
From: Rob Herring @ 2016-11-23 23:01 UTC (permalink / raw)
To: Andrew F. Davis
Cc: Nishanth Menon, Mark Rutland, devicetree, linux-kernel,
Tero Kristo, Philipp Zabel, Santosh Shilimkar, linux-arm-kernel
In-Reply-To: <20161121213052.8684-2-afd@ti.com>
On Mon, Nov 21, 2016 at 03:30:51PM -0600, Andrew F. Davis wrote:
> Add TI SCI reset controller binding. This describes the DT binding
> details for a reset controller node providing reset management services
> to hardware blocks (reset consumers) using the Texas Instrument's System
> Control Interface (TI SCI) protocol to communicate to a system controller
> block present on the SoC.
>
> Signed-off-by: Andrew F. Davis <afd@ti.com>
> [s-anna@ti.com: revise the binding format]
> Signed-off-by: Suman Anna <s-anna@ti.com>
> Signed-off-by: Nishanth Menon <nm@ti.com>
> Acked-by: Santosh Shilimkar <ssantosh@kernel.org>
> ---
> .../devicetree/bindings/reset/ti,sci-reset.txt | 66 ++++++++++++++++++++++
> MAINTAINERS | 2 +
> include/dt-bindings/reset/k2g.h | 22 ++++++++
> 3 files changed, 90 insertions(+)
> create mode 100644 Documentation/devicetree/bindings/reset/ti,sci-reset.txt
> create mode 100644 include/dt-bindings/reset/k2g.h
Acked-by: Rob Herring <robh@kernel.org>
^ permalink raw reply
* Re: [PATCH 2/2] Add support for the Nexbox A1 board based on the Amlogic S912 SoC.
From: Rob Herring @ 2016-11-23 22:52 UTC (permalink / raw)
To: Neil Armstrong
Cc: khilman-rdvid1DuHRBWk0Htik3J/w, carlo-KA+7E9HrN00dnm+yROfE0A,
linux-amlogic-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <20161121162905.14285-3-narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On Mon, Nov 21, 2016 at 05:29:05PM +0100, Neil Armstrong wrote:
> Signed-off-by: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> ---
> Documentation/devicetree/bindings/arm/amlogic.txt | 1 +
> arch/arm64/boot/dts/amlogic/Makefile | 1 +
> .../arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts | 169 +++++++++++++++++++++
> 3 files changed, 171 insertions(+)
> create mode 100644 arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
A few nits below, otherwise:
Acked-by: Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org>
>
> diff --git a/Documentation/devicetree/bindings/arm/amlogic.txt b/Documentation/devicetree/bindings/arm/amlogic.txt
> index 1144214..6ef7c52 100644
> --- a/Documentation/devicetree/bindings/arm/amlogic.txt
> +++ b/Documentation/devicetree/bindings/arm/amlogic.txt
> @@ -45,3 +45,4 @@ Board compatible values:
> - "amlogic,p231" (Meson gxl s905d)
> - "amlogic,q200" (Meson gxm s912)
> - "amlogic,q201" (Meson gxm s912)
> + - "nexbox,a1" (Meson gxm s912)
> diff --git a/arch/arm64/boot/dts/amlogic/Makefile b/arch/arm64/boot/dts/amlogic/Makefile
> index 7752a16..2fbb8e3 100644
> --- a/arch/arm64/boot/dts/amlogic/Makefile
> +++ b/arch/arm64/boot/dts/amlogic/Makefile
> @@ -10,6 +10,7 @@ dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p230.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-gxl-s905d-p231.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-q200.dtb
> dtb-$(CONFIG_ARCH_MESON) += meson-gxm-s912-q201.dtb
> +dtb-$(CONFIG_ARCH_MESON) += meson-gxm-nexbox-a1.dtb
>
> always := $(dtb-y)
> subdir-y := $(dts-dirs)
> diff --git a/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
> new file mode 100644
> index 0000000..d320727
> --- /dev/null
> +++ b/arch/arm64/boot/dts/amlogic/meson-gxm-nexbox-a1.dts
> @@ -0,0 +1,169 @@
> +/*
> + * Copyright (c) 2016 BayLibre, SAS.
> + * Author: Neil Armstrong <narmstrong-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
> + *
> + * Copyright (c) 2016 Endless Computers, Inc.
> + * Author: Carlo Caione <carlo-6IF/jdPJHihWk0Htik3J/w@public.gmane.org>
> + *
> + * This file is dual-licensed: you can use it either under the terms
> + * of the GPL or the X11 license, at your option. Note that this dual
> + * licensing only applies to this file, and not this project as a
> + * whole.
> + *
> + * a) This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU General Public License as
> + * published by the Free Software Foundation; either version 2 of the
> + * License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> + * GNU General Public License for more details.
> + *
> + * Or, alternatively,
> + *
> + * b) Permission is hereby granted, free of charge, to any person
> + * obtaining a copy of this software and associated documentation
> + * files (the "Software"), to deal in the Software without
> + * restriction, including without limitation the rights to use,
> + * copy, modify, merge, publish, distribute, sublicense, and/or
> + * sell copies of the Software, and to permit persons to whom the
> + * Software is furnished to do so, subject to the following
> + * conditions:
> + *
> + * The above copyright notice and this permission notice shall be
> + * included in all copies or substantial portions of the Software.
> + *
> + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
> + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
> + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
> + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
> + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
> + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
> + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
> + * OTHER DEALINGS IN THE SOFTWARE.
> + */
> +
> +/dts-v1/;
> +
> +#include "meson-gxm.dtsi"
> +
> +/ {
> + compatible = "nexbox,a1", "amlogic,s912", "amlogic,meson-gxm";
> + model = "NEXBOX A1";
> +
> + aliases {
> + serial0 = &uart_AO;
> + };
> +
> + chosen {
> + stdout-path = "serial0:115200n8";
> + };
> +
> + memory@0 {
> + device_type = "memory";
> + reg = <0x0 0x0 0x0 0x80000000>;
> + };
> +
> + vddio_boot: regulator-vddio_boot {
Don't use '_' in node names.
> + compatible = "regulator-fixed";
> + regulator-name = "VDDIO_BOOT";
> + regulator-min-microvolt = <1800000>;
> + regulator-max-microvolt = <1800000>;
> + };
> +
> + vddao_3v3: regulator-vddao_3v3 {
ditto
> + compatible = "regulator-fixed";
> + regulator-name = "VDDAO_3V3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + vcc_3v3: regulator-vcc_3v3 {
ditto
> + compatible = "regulator-fixed";
> + regulator-name = "VCC_3V3";
> + regulator-min-microvolt = <3300000>;
> + regulator-max-microvolt = <3300000>;
> + };
> +
> + emmc_pwrseq: emmc-pwrseq {
> + compatible = "mmc-pwrseq-emmc";
> + reset-gpios = <&gpio BOOT_9 GPIO_ACTIVE_LOW>;
> + };
> +};
> +
> +/* This UART is brought out to the DB9 connector */
> +&uart_AO {
> + status = "okay";
> + pinctrl-0 = <&uart_ao_a_pins>;
> + pinctrl-names = "default";
> +};
> +
> +&ir {
> + status = "okay";
> + pinctrl-0 = <&remote_input_ao_pins>;
> + pinctrl-names = "default";
> +};
> +
> +/* SD card */
> +&sd_emmc_b {
> + status = "okay";
> + pinctrl-0 = <&sdcard_pins>;
> + pinctrl-names = "default";
> +
> + bus-width = <4>;
> + cap-sd-highspeed;
> + max-frequency = <100000000>;
> + disable-wp;
> +
> + cd-gpios = <&gpio CARD_6 GPIO_ACTIVE_HIGH>;
> + cd-inverted;
> +
> + vmmc-supply = <&vddao_3v3>;
> + vqmmc-supply = <&vddio_boot>;
> +};
> +
> +/* eMMC */
> +&sd_emmc_c {
> + status = "okay";
> + pinctrl-0 = <&emmc_pins>;
> + pinctrl-names = "default";
> +
> + bus-width = <8>;
> + cap-sd-highspeed;
> + cap-mmc-highspeed;
> + max-frequency = <200000000>;
> + non-removable;
> + disable-wp;
> + mmc-ddr-1_8v;
> + mmc-hs200-1_8v;
> +
> + mmc-pwrseq = <&emmc_pwrseq>;
> + vmmc-supply = <&vcc_3v3>;
> + vqmmc-supply = <&vddio_boot>;
> +};
> +
> +ðmac {
> + status = "okay";
> +
> + pinctrl-0 = <ð_pins>;
> + pinctrl-names = "default";
> +
> + /* Select external PHY by default */
> + phy-handle = <&external_phy>;
> +
> + snps,reset-gpio = <&gpio GPIOZ_14 0>;
> + snps,reset-delays-us = <0 10000 1000000>;
> + snps,reset-active-low;
> +
> + /* External PHY is in RGMII */
> + phy-mode = "rgmii";
> +};
> +
> +&external_mdio {
> + external_phy: ethernet-phy@0 {
> + compatible = "ethernet-phy-id001c.c916", "ethernet-phy-ieee802.3-c22";
> + reg = <0>;
> + max-speed = <1000>;
> + };
> +};
> --
> 2.7.0
>
> --
> To unsubscribe from this list: send the line "unsubscribe devicetree" in
> the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] ARM: dts: da850: add the mstpri and ddrctl nodes
From: David Lechner @ 2016-11-23 22:48 UTC (permalink / raw)
To: Kevin Hilman
Cc: Bartosz Golaszewski, Michael Turquette, Sekhar Nori, Rob Herring,
Frank Rowand, Mark Rutland, Peter Ujfalusi, Russell King,
linux-devicetree, David Airlie, LKML, linux-drm, Tomi Valkeinen,
Jyri Sarha, arm-soc, Laurent Pinchart
In-Reply-To: <m2bmx5x1y2.fsf-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
On 11/23/2016 04:32 PM, Kevin Hilman wrote:
> David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org> writes:
>
>> On 11/23/2016 04:27 AM, Bartosz Golaszewski wrote:
>>> 2016-11-22 23:23 GMT+01:00 David Lechner <david-nq/r/kbU++upp/zk7JDF2g@public.gmane.org>:
>>>> On 11/15/2016 05:00 AM, Bartosz Golaszewski wrote:
>>>>>
>>>>> Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
>>>>> controller drivers to da850.dtsi.
>>>>>
>>>>> Signed-off-by: Bartosz Golaszewski <bgolaszewski-rdvid1DuHRBWk0Htik3J/w@public.gmane.org>
>>>>> ---
>>>>> v1 -> v2:
>>>>> - moved the priority controller node above the cfgchip node
>>>>> - renamed added nodes to better reflect their purpose
>>>>>
>>>>> arch/arm/boot/dts/da850.dtsi | 8 ++++++++
>>>>> 1 file changed, 8 insertions(+)
>>>>>
>>>>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>>>>> index 1bb1f6d..412eec6 100644
>>>>> --- a/arch/arm/boot/dts/da850.dtsi
>>>>> +++ b/arch/arm/boot/dts/da850.dtsi
>>>>> @@ -210,6 +210,10 @@
>>>>> };
>>>>>
>>>>> };
>>>>> + prictrl: priority-controller@14110 {
>>>>> + compatible = "ti,da850-mstpri";
>>>>> + reg = <0x14110 0x0c>;
>>>>
>>>>
>>>> I think we should add status = "disabled"; here and let boards opt in.
>>>>
>>>>> + };
>>>>> cfgchip: chip-controller@1417c {
>>>>> compatible = "ti,da830-cfgchip", "syscon",
>>>>> "simple-mfd";
>>>>> reg = <0x1417c 0x14>;
>>>>> @@ -451,4 +455,8 @@
>>>>> 1 0 0x68000000 0x00008000>;
>>>>> status = "disabled";
>>>>> };
>>>>> + memctrl: memory-controller@b0000000 {
>>>>> + compatible = "ti,da850-ddr-controller";
>>>>> + reg = <0xb0000000 0xe8>;
>>>>
>>>>
>>>> same here. status = "disabled";
>>>>
>>>>> + };
>>>>> };
>>>>>
>>>
>>> Hi David,
>>>
>>> I did that initially[1][2] and it was rejected by Kevin[3] and Laurent[4].
>>>
>>> FYI this patch has already been queued by Sekhar.
>>
>> Thanks. I did not see those threads.
>>
>> FYI to maintainers, having these enabled by default causes error
>> messages in the kernel log for other boards that are not supported by
>> the drivers.
>
> Then the driver is too noisy and should be cleaned up.
>
>> Since there is only one board that is supported and soon
>> to be 2 that are not, I would rather have this disabled by default to
>> avoid the error messages.
>
> IMO, what exactly are the error messages? Sounds like the driver is
> being too verbose, and calling things errors that are not really errors.
It is just one line per driver.
dev_err(dev, "no master priorities defined for this board\n");
and
dev_err(dev, "no settings defined for this board\n");
Since "ti,da850-lcdk" is the only board supported in these drivers, all
other boards will see these error messages.
Also, these modules will be loaded and taking up memory on boards that
don't use them. This not really a big deal and they can be explicitly
disabled, so maybe it was not worth mentioning.
>
> Kevin
>
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH RFC] ARM: dts: add support for Turris Omnia
From: tomas.hlavacek @ 2016-11-23 22:45 UTC (permalink / raw)
To: Andrew Lunn
Cc: Mark Rutland, marex, Jason Cooper, Uwe Kleine-König,
devicetree, Rob Herring, Gregory Clement, linux-arm-kernel,
Sebastian Hesselbarth
In-Reply-To: <20161123145916.GL14947@lunn.ch>
Hi Andrew!
On Wed, Nov 23, 2016 at 3:59 PM, Andrew Lunn <andrew@lunn.ch> wrote:
>> >CZ11NIC12 is indicated on my board.
>>
>> :-( Well, this board version has wrongly matched length of some
>> differential pairs, IRQ from 88E1514 is connected differently, there
>> are slight differences in power supplies and (if I am not mistaken)
>> something changed in RTC support circuitry. It looks like a huge
>> mistake on our side.
>
> Hi Tomas
>
> Would these problems also explain why the Ethernet links to the switch
> don't work? Maybe the differential pairs?
I do not think so. The ethernet links to the switch are RGMII, not
differential pairs. Differential pair is used only for the eth2 to link
either SFP+ or 88E1514 (via a high-speed switch that selects one or
another). So the problems with differential pairs affect only WAN
interface.
>
>
>> It seems that libphy is probed before pca9538 and we end up with:
>> [ 4.217550] libphy: orion_mdio_bus: probed
>> [ 4.221777] irq: no irq domain found for
>> /soc/internal-regs/i2c@11000/i2cmux@70/i2c@7/gpio@71 !
>>
>> Any clue where to look in order to defer probing libphy or at least
>> orion_mdio_bus?
>
> I think there is a known phylib problem here. Somewhere in the call
> chain there is a void function, so the EPROBE_DEFFER gets
> discarded. But i could be remembering this wrongly.
Oh yes, I thought that and I tried to find exactly this type of problem
yesterday, but I didn't succeed. But I think that we agreed that we are
going to stick with PHY polling rather then experimenting with
unreliable IRQ over the GPIO expander, so we can leave this unresolved.
I will look into the I2C mux concerns, fix the remaining comments
regarding my version and test RTC more extensively - Uwe's board is
still not ticking, mine does, so we have to rule out that it is a
common problem.
Tomas
^ permalink raw reply
* Re: [PATCH 3/3] ARM: dts: da850: Add node for pullup/pulldown pinconf
From: Kevin Hilman @ 2016-11-23 22:33 UTC (permalink / raw)
To: David Lechner
Cc: Sekhar Nori, Linus Walleij, Rob Herring, Mark Rutland, linux-gpio,
devicetree, linux-kernel, linux-arm-kernel, Axel Haslam,
Alexandre Bailon, Bartosz Gołaszewski
In-Reply-To: <06bc8517-8c33-85a1-9d5a-29042c7281db@lechnology.com>
David Lechner <david@lechnology.com> writes:
> On 11/23/2016 05:12 AM, Sekhar Nori wrote:
>> On Wednesday 23 November 2016 08:59 AM, David Lechner wrote:
>>> This SoC has a separate pin controller for configuring pullup/pulldown
>>> bias on groups of pins.
>>>
>>> Signed-off-by: David Lechner <david@lechnology.com>
>>> ---
>>> arch/arm/boot/dts/da850.dtsi | 5 +++++
>>> 1 file changed, 5 insertions(+)
>>>
>>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>>> index 8945815..1c0224c 100644
>>> --- a/arch/arm/boot/dts/da850.dtsi
>>> +++ b/arch/arm/boot/dts/da850.dtsi
>>> @@ -210,6 +210,11 @@
>>> };
>>>
>>> };
>>> + pinconf: pin-controller@22c00c {
>>> + compatible = "ti,da850-pupd";
>>> + reg = <0x22c00c 0x8>;
>>> + status = "disabled";
>>> + };
>>
>> Can you please place this below the i2c1 node. I am trying to keep the
>> nodes sorted by unit address. I know thats broken in many places today,
>> but lets add the new ones where they should eventually end up.
>
> I can do this, but it seems that the predominant sorting pattern here
> is to keep subsystems together (e.g. all i2c are together, all uart
> are together, etc.)
>
> Would a separate patch to sort everything by unit address to get this
> cleaned up be acceptable?
No thanks. That kind of thing is the needless churn that gets us flamed.
Kevin
^ permalink raw reply
* Re: [PATCH v2] ARM: dts: da850: add the mstpri and ddrctl nodes
From: Kevin Hilman @ 2016-11-23 22:32 UTC (permalink / raw)
To: David Lechner
Cc: Mark Rutland, linux-devicetree, Tomi Valkeinen, Michael Turquette,
Sekhar Nori, Russell King, linux-drm, LKML, Peter Ujfalusi,
Bartosz Golaszewski, Rob Herring, Jyri Sarha, Frank Rowand,
arm-soc, Laurent Pinchart
In-Reply-To: <5e647eb0-2f8a-b46b-2048-7616bfb54ad7@lechnology.com>
David Lechner <david@lechnology.com> writes:
> On 11/23/2016 04:27 AM, Bartosz Golaszewski wrote:
>> 2016-11-22 23:23 GMT+01:00 David Lechner <david@lechnology.com>:
>>> On 11/15/2016 05:00 AM, Bartosz Golaszewski wrote:
>>>>
>>>> Add the nodes for the MSTPRI configuration and DDR2/mDDR memory
>>>> controller drivers to da850.dtsi.
>>>>
>>>> Signed-off-by: Bartosz Golaszewski <bgolaszewski@baylibre.com>
>>>> ---
>>>> v1 -> v2:
>>>> - moved the priority controller node above the cfgchip node
>>>> - renamed added nodes to better reflect their purpose
>>>>
>>>> arch/arm/boot/dts/da850.dtsi | 8 ++++++++
>>>> 1 file changed, 8 insertions(+)
>>>>
>>>> diff --git a/arch/arm/boot/dts/da850.dtsi b/arch/arm/boot/dts/da850.dtsi
>>>> index 1bb1f6d..412eec6 100644
>>>> --- a/arch/arm/boot/dts/da850.dtsi
>>>> +++ b/arch/arm/boot/dts/da850.dtsi
>>>> @@ -210,6 +210,10 @@
>>>> };
>>>>
>>>> };
>>>> + prictrl: priority-controller@14110 {
>>>> + compatible = "ti,da850-mstpri";
>>>> + reg = <0x14110 0x0c>;
>>>
>>>
>>> I think we should add status = "disabled"; here and let boards opt in.
>>>
>>>> + };
>>>> cfgchip: chip-controller@1417c {
>>>> compatible = "ti,da830-cfgchip", "syscon",
>>>> "simple-mfd";
>>>> reg = <0x1417c 0x14>;
>>>> @@ -451,4 +455,8 @@
>>>> 1 0 0x68000000 0x00008000>;
>>>> status = "disabled";
>>>> };
>>>> + memctrl: memory-controller@b0000000 {
>>>> + compatible = "ti,da850-ddr-controller";
>>>> + reg = <0xb0000000 0xe8>;
>>>
>>>
>>> same here. status = "disabled";
>>>
>>>> + };
>>>> };
>>>>
>>
>> Hi David,
>>
>> I did that initially[1][2] and it was rejected by Kevin[3] and Laurent[4].
>>
>> FYI this patch has already been queued by Sekhar.
>
> Thanks. I did not see those threads.
>
> FYI to maintainers, having these enabled by default causes error
> messages in the kernel log for other boards that are not supported by
> the drivers.
Then the driver is too noisy and should be cleaned up.
> Since there is only one board that is supported and soon
> to be 2 that are not, I would rather have this disabled by default to
> avoid the error messages.
IMO, what exactly are the error messages? Sounds like the driver is
being too verbose, and calling things errors that are not really errors.
Kevin
_______________________________________________
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel
^ permalink raw reply
* Re: [PATCH v2 2/3] drm/bridge: Add ti-tfp410 DVI transmitter driver
From: Rob Herring @ 2016-11-23 22:30 UTC (permalink / raw)
To: Laurent Pinchart
Cc: Jyri Sarha, dri-devel,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, David Airlie,
Daniel Vetter, Tomi Valkeinen, Rob Clark, Bartosz Golaszewski,
Kevin Hilman, Benoit Cousson
In-Reply-To: <1829466.vPTafcVR8L@avalon>
On Thu, Nov 17, 2016 at 3:45 AM, Laurent Pinchart
<laurent.pinchart-ryLnwIuWjnjg/C1BVhZhaw@public.gmane.org> wrote:
> Hi Jyri,
>
> On Wednesday 16 Nov 2016 16:39:28 Jyri Sarha wrote:
>> On 11/16/16 15:33, Rob Herring wrote:
>> >> +Optional properties
>> >>
>> >>> + - reg: I2C address. If and only if present the driver node
>
> I assume you meant device node, not driver node ?
>
>> >>> + should be placed into the i2c controller node where the
>> >>> + tfp410 i2c is connected to (the current implementation does
>> >>> + not yet support this).
>> >
>> > So this chip can work without programming I guess?
>>
>> Yes. Just powering it up is enough for most application.
>>
>> > reg should only be not present if I2C is not connected in the design. It
>> > can't be a function of what the driver supports. In otherwords, you
>> > can't be moving this node around based on when you add I2C control.
>>
>> Ok, I'll try to implement a dummy i2c driver at the same time too. I can
>> not test anything related to it because I do not have a piece of HW with
>> tfp410 i2c wires connected, but it should not matter as long as I am
>> able to probe it as a i2c client.
>
> I think that Rob's point was that whether the current implementation supports
> this or not is irrelevant from a DT bindings point of view. It should not be
> mentioned in the bindings document.
Right. Now, whether the h/w has I2C wires connected or not is relevant
to the binding doc. So the doc just needs some rewording, a dummy
driver isn't needed.
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 1/2] PM / Domains: Introduce domain-performance-state binding
From: Kevin Hilman @ 2016-11-23 22:30 UTC (permalink / raw)
To: Vincent Guittot
Cc: Viresh Kumar, Rob Herring, Rafael Wysocki,
linaro-kernel@lists.linaro.org, linux-pm@vger.kernel.org,
linux-kernel, Mark Rutland, Ulf Hansson, Lina Iyer,
devicetree@vger.kernel.org, Stephen Boyd, Nayak Rajendra
In-Reply-To: <CAKfTPtBMro7+UruF0-E26TJPu6pEAvkjF9V7SKriNBm5q+K9+A@mail.gmail.com>
Vincent Guittot <vincent.guittot@linaro.org> writes:
> On 23 November 2016 at 16:51, Kevin Hilman <khilman@baylibre.com> wrote:
>> Vincent Guittot <vincent.guittot@linaro.org> writes:
>>
>>> On 22 November 2016 at 19:12, Kevin Hilman <khilman@baylibre.com> wrote:
>>>> Viresh Kumar <viresh.kumar@linaro.org> writes:
>>>>
>>>>> On 21-11-16, 09:07, Rob Herring wrote:
>>>>>> On Fri, Nov 18, 2016 at 02:53:12PM +0530, Viresh Kumar wrote:
>>>>>> > Some platforms have the capability to configure the performance state of
>>>>>> > their Power Domains. The performance levels are represented by positive
>>>>>> > integer values, a lower value represents lower performance state.
>>>>>> >
>>>>>> > The power-domains until now were only concentrating on the idle state
>>>>>> > management of the device and this needs to change in order to reuse the
>>>>>> > infrastructure of power domains for active state management.
>>>>>> >
>>>>>> > This patch introduces a new optional property for the consumers of the
>>>>>> > power-domains: domain-performance-state.
>>>>>> >
>>>>>> > If the consumers don't need the capability of switching to different
>>>>>> > domain performance states at runtime, then they can simply define their
>>>>>> > required domain performance state in their node directly. Otherwise the
>>>>>> > consumers can define their requirements with help of other
>>>>>> > infrastructure, for example the OPP table.
>>>>>> >
>>>>>> > Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
>>>>>> > ---
>>>>>> > Documentation/devicetree/bindings/power/power_domain.txt | 6 ++++++
>>>>>> > 1 file changed, 6 insertions(+)
>>>>>> >
>>>>>> > diff --git a/Documentation/devicetree/bindings/power/power_domain.txt b/Documentation/devicetree/bindings/power/power_domain.txt
>>>>>> > index e1650364b296..db42eacf8b5c 100644
>>>>>> > --- a/Documentation/devicetree/bindings/power/power_domain.txt
>>>>>> > +++ b/Documentation/devicetree/bindings/power/power_domain.txt
>>>>>> > @@ -106,6 +106,12 @@ domain provided by the 'parent' power controller.
>>>>>> > - power-domains : A phandle and PM domain specifier as defined by bindings of
>>>>>> > the power controller specified by phandle.
>>>>>> >
>>>>>> > +Optional properties:
>>>>>> > +- domain-performance-state: A positive integer value representing the minimum
>>>>>> > + performance level (of the parent domain) required by the consumer for its
>>>>>> > + working. The integer value '1' represents the lowest performance level and the
>>>>>> > + highest value represents the highest performance level.
>>>>>>
>>>>>> How does one come up with the range of values?
>>>>>
>>>>> Why would we need a range here? The value here represents the minimum 'state'
>>>>> and the assumption is that everything above that level would be fine. So the
>>>>> range is automatically: domain-performance-state -> MAX.
>>>>>
>>>>>> It seems like you are
>>>>>> just making up numbers. Couldn't the domain performance level be an OPP
>>>>>> in the sense that it is a collection of clock frequencies and voltage
>>>>>> settings?
>>>>>
>>>>> The clock is going to be handled by the device itself (at least for the case we
>>>>> have today) and the performance-state lies with the power-domain which is
>>>>> configured separately. If the performance level includes both clk and voltage,
>>>>> then why would we need to show the clock rates in the DT ? Wouldn't a
>>>>> performance level be enough in such cases?
>>>>
>>>> I think the question is: what does the performance-level of a domain
>>>> actually mean? Or, what are the units?
>>>>
>>>> Depending on the SoC, there's probably a few things this could mean. It
>>>> might mean is that an underlying bus/interconnect can be configured to
>>>> guarantee a specific bandwidth or throughput. That in turn might mean
>>>> that that bus/interconnect might have to be set at a specific
>>>> frequency/voltage.
>>>>
>>>> In your case, IIUC, you're just passing some magic value to some
>>>> firmware running on a micro-controller, but under the hood that uC is
>>>> probably configuring a frequency/voltage someplace.
>>>
>>> In the case described by Viresh, it's only about setting the voltage
>>> of a power domain that is shared between different devices. these
>>> devices wants to run at different frequency (set by the devices) but
>>> we have to select a Volateg value that will match with the constraint
>>> of all devices (in this case the highest voltage)
>>
>> Then, at least for this use case, we're talking about voltage, not some
>> unspecified units.
>>
>> But that makes me wonder, this performance state sounds like something
>> that is changing dynamically at runtime, so why do you want to describe
>> this statically in DT?
>>
>> This sounds to me like the job of the genpd. When any device in the
>> domain does its pm_runtime_get(), the domain could check the device
>> frequency and see if it needs to change the domain voltage in order for
>> that device to operate at that frequency. When the device goes away
>> (using pm_runtime_put()) the domain can check again if it could lower
>> the voltage and still meet the requirements of the remaining devices.
>
> That's only part of the job. The device can change its frequency and
> as a result ask for a new voltage index while it is already running
That's fine. Use clock notifiers, or better use QoS (with notifiers) so
that the genpd knows when any of those change.
Kevin
^ permalink raw reply
* Re: [PATCH] of: Fix issue where code would fall through to error case.
From: Rob Herring @ 2016-11-23 21:58 UTC (permalink / raw)
To: Moritz Fischer
Cc: Frank Rowand, Moritz Fischer, linux-kernel@vger.kernel.org,
Pantelis Antoniou, moritz, devicetree@vger.kernel.org
In-Reply-To: <CAJYdmeNnKtecshe3QSZCPnwEuNUFAW9cUsNS-Z1Chw7OPUJ2jQ@mail.gmail.com>
On Thu, Nov 17, 2016 at 6:10 PM, Moritz Fischer
<moritz.fischer.private@gmail.com> wrote:
> On Thu, Nov 17, 2016 at 4:02 PM, Frank Rowand <frowand.list@gmail.com> wrote:
>> On 11/17/16 15:40, Frank Rowand wrote:
>>> On 11/17/16 15:25, Moritz Fischer wrote:
>>>> No longer fall through into the error case that prints out
>>>> an error if no error (err = 0) occurred.
>>>>
>>>> Fixes d9181b20a83(of: Add back an error message, restructured)
>>>> Signed-off-by: Moritz Fischer <moritz.fischer@ettus.com>
>>>> ---
>>>> drivers/of/resolver.c | 6 +++++-
>>>> 1 file changed, 5 insertions(+), 1 deletion(-)
>>>>
>>>> diff --git a/drivers/of/resolver.c b/drivers/of/resolver.c
>>>> index 783bd09..785076d 100644
>>>> --- a/drivers/of/resolver.c
>>>> +++ b/drivers/of/resolver.c
>>>> @@ -358,9 +358,13 @@ int of_resolve_phandles(struct device_node *overlay)
>>>>
>>>> err = update_usages_of_a_phandle_reference(overlay, prop, phandle);
>>>> if (err)
>>>> - break;
>>>> + goto err_out;
>>>> }
>>>>
>>>> + of_node_put(tree_symbols);
>>>> +
>>>> + return 0;
>>>> +
>>>> err_out:
>>>> pr_err("overlay phandle fixup failed: %d\n", err);
>>>> out:
>>>
>>> Thanks for catching that.
>>>
>>> Rob, please apply.
>>>
>>> Reviewed-by: Frank Rowand <frank.rowand@am.sony.com>
>>>
>>> -Frank
>>
>> On second thought, isn't the common pattern when clean up is needed for
>> both the no-error path and the error path something like:
>>
>>
>> out:
>> of_node_put(tree_symbols);
>> return err;
>>
>> err_out:
>> pr_err("overlay phandle fixup failed: %d\n", err);
>> goto out;
>> }
>>
>>
>> I don't have a strong opinion, whatever Rob wants to take is fine with me.
>
> Same here. I tried to avoid the jumping back part, but if that's the
> common pattern,
> I can submit a v2 doing that instead.
Both are ugly. Just do:
if (err)
pr_err(...);
Rob
^ permalink raw reply
* Re: [PATCH] drivers/of: Export phandle iterators
From: Rob Herring @ 2016-11-23 21:49 UTC (permalink / raw)
To: Robin Murphy
Cc: devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
Frank Rowand
In-Reply-To: <a1fa1157cab10f2a6f319d431d355cef79b91820.1479927866.git.robin.murphy-5wv7dgnIgG8@public.gmane.org>
On Wed, Nov 23, 2016 at 1:06 PM, Robin Murphy <robin.murphy-5wv7dgnIgG8@public.gmane.org> wrote:
> Modular drivers may want to use of_for_each_phandle() - export its
> constituent functions.
Do you have a user?
Rob
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH] ALSA SoC MAX98927 driver - Initial release
From: Michael Trimarchi @ 2016-11-23 19:20 UTC (permalink / raw)
To: Ryan Lee
Cc: Liam Girdwood, Mark Brown, Rob Herring, Mark Rutland,
Jaroslav Kysela, Takashi Iwai, Arnd Bergmann, Oder Chiou,
yesanishhere-Re5JQEeQqe8AvxtiuMwx3w, Jacob Siverskog,
Damien.Horsley-1AXoQHu6uovQT0dZR+AlfA, Bard Liao,
kuninori.morimoto.gx-zM6kxYcvzFBBDgjK7y7TUQ,
petr-Qh/3xLP0EvwAvxtiuMwx3w, Lars-Peter Clausen, nh6z-fFIq/eER6g8,
alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw@public.gmane.org,
devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org, LKML
In-Reply-To: <1479877026-5172-1-git-send-email-RyanS.Lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
Hi
On Wed, Nov 23, 2016 at 5:57 AM, Ryan Lee <RyanS.Lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org> wrote:
> Signed-off-by: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> ---
> .../devicetree/bindings/sound/max98927.txt | 32 +
> sound/soc/codecs/Kconfig | 5 +
> sound/soc/codecs/Makefile | 2 +
> sound/soc/codecs/max98927.c | 954 +++++++++++++++
> sound/soc/codecs/max98927.h | 1253 ++++++++++++++++++++
> 5 files changed, 2246 insertions(+)
> create mode 100755 Documentation/devicetree/bindings/sound/max98927.txt
> mode change 100644 => 100755 sound/soc/codecs/Kconfig
> mode change 100644 => 100755 sound/soc/codecs/Makefile
> create mode 100755 sound/soc/codecs/max98927.c
> create mode 100755 sound/soc/codecs/max98927.h
>
> diff --git a/Documentation/devicetree/bindings/sound/max98927.txt b/Documentation/devicetree/bindings/sound/max98927.txt
> new file mode 100755
> index 0000000..ddcd332
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/sound/max98927.txt
> @@ -0,0 +1,32 @@
> +max98927 audio CODEC
> +
> +This device supports I2C.
> +
> +Required properties:
> +
> + - compatible : "maxim,max98927"
> +
> + - vmon-slot-no : slot number used to send voltage information
> + or in inteleave mode this will be used as
> + interleave slot.
> +
> + - imon-slot-no : slot number used to send current information
> +
> + - interleave-mode : When using two MAX98927 in a system it is
> + possible to create ADC data that that will
> + overflow the frame size. Digital Audio Interleave
> + mode provides a means to output VMON and IMON data
> + from two devices on a single DOUT line when running
> + smaller frames sizes such as 32 BCLKS per LRCLK or
> + 48 BCLKS per LRCLK.
> +
> + - reg : the I2C address of the device for I2C
> +
> +Example:
> +
> +codec: max98927@3a {
> + compatible = "maxim,max98927";
> + vmon-slot-no = <1>;
> + imon-slot-no = <0>;
> + reg = <0x3a>;
> +};
> diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig
> old mode 100644
> new mode 100755
> index c67667b..45f21ca
> --- a/sound/soc/codecs/Kconfig
> +++ b/sound/soc/codecs/Kconfig
> @@ -86,6 +86,7 @@ config SND_SOC_ALL_CODECS
> select SND_SOC_MAX9867 if I2C
> select SND_SOC_MAX98925 if I2C
> select SND_SOC_MAX98926 if I2C
> + select SND_SOC_MAX98927 if I2C
> select SND_SOC_MAX9850 if I2C
> select SND_SOC_MAX9860 if I2C
> select SND_SOC_MAX9768 if I2C
> @@ -573,6 +574,10 @@ config SND_SOC_MAX98925
> config SND_SOC_MAX98926
> tristate
>
> +config SND_SOC_MAX98927
> + tristate "Maxim Integrated MAX98927 Speaker Amplifier"
> + depends on I2C
> +
> config SND_SOC_MAX9850
> tristate
>
> diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile
> old mode 100644
> new mode 100755
> index 958cd49..1f5fe2c
> --- a/sound/soc/codecs/Makefile
> +++ b/sound/soc/codecs/Makefile
> @@ -82,6 +82,7 @@ snd-soc-max98371-objs := max98371.o
> snd-soc-max9867-objs := max9867.o
> snd-soc-max98925-objs := max98925.o
> snd-soc-max98926-objs := max98926.o
> +snd-soc-max98927-objs := max98927.o
> snd-soc-max9850-objs := max9850.o
> snd-soc-max9860-objs := max9860.o
> snd-soc-mc13783-objs := mc13783.o
> @@ -306,6 +307,7 @@ obj-$(CONFIG_SND_SOC_MAX98357A) += snd-soc-max98357a.o
> obj-$(CONFIG_SND_SOC_MAX9867) += snd-soc-max9867.o
> obj-$(CONFIG_SND_SOC_MAX98925) += snd-soc-max98925.o
> obj-$(CONFIG_SND_SOC_MAX98926) += snd-soc-max98926.o
> +obj-$(CONFIG_SND_SOC_MAX98927) += snd-soc-max98927.o
> obj-$(CONFIG_SND_SOC_MAX9850) += snd-soc-max9850.o
> obj-$(CONFIG_SND_SOC_MAX9860) += snd-soc-max9860.o
> obj-$(CONFIG_SND_SOC_MC13783) += snd-soc-mc13783.o
> diff --git a/sound/soc/codecs/max98927.c b/sound/soc/codecs/max98927.c
> new file mode 100755
> index 0000000..d85c84f
> --- /dev/null
> +++ b/sound/soc/codecs/max98927.c
> @@ -0,0 +1,954 @@
> +/*
> + * max98927.c -- MAX98927 ALSA Soc Audio driver
> + *
> + * Copyright 2013-15 Maxim Integrated Products
> + * Author: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + */
> +
> +#include <linux/delay.h>
> +#include <linux/i2c.h>
> +#include <linux/module.h>
> +#include <linux/regmap.h>
> +#include <linux/slab.h>
> +#include <linux/cdev.h>
> +#include <sound/pcm.h>
> +#include <sound/pcm_params.h>
> +#include <sound/soc.h>
> +#include <linux/gpio.h>
> +#include <linux/of_gpio.h>
> +#include <sound/tlv.h>
> +#include "max98927.h"
> +
> +static struct reg_default max98927_reg_map[] = {
> + {0x0014, 0x78},
> + {0x0015, 0xFF},
> + {0x0043, 0x04},
> + {0x0017, 0x55},
> + /* For mono driver we are just enabling one channel*/
> + {MAX98927_PCM_Rx_Enables_A, 0x03},
> + {MAX98927_PCM_Tx_HiZ_Control_A, 0xfc},
> + {MAX98927_PCM_Tx_HiZ_Control_B, 0xff},
> + {MAX98927_PCM_Tx_Channel_Sources_A, 0x01},
> + {MAX98927_PCM_Tx_Channel_Sources_B, 0x01},
> + {MAX98927_Measurement_DSP_Config, 0xf7},
What about not use camel case
> + {0x0025, 0x80},
> + {0x0026, 0x01},
> + {0x0035, 0x40},
> + {0x0036, 0x40},
> + {0x0037, 0x02},
> + {0x0039, 0x01},
> + {0x003c, 0x44},
> + {0x003d, 0x04},
> + {0x0040, 0x10},
> + {0x0042, 0x3f},
> + {0x0044, 0x00},
> + {0x0045, 0x24},
> + {0x007f, 0x06},
> + {0x0087, 0x1c},
> + {0x0089, 0x03},
> + {0x009f, 0x01},
> +};
> +
> +void max98927_wrapper_write(struct max98927_priv *max98927,
> + unsigned int reg, unsigned int val)
> +{
> + if (max98927->regmap)
> + regmap_write(max98927->regmap, reg, val);
> + if (max98927->sub_regmap)
> + regmap_write(max98927->sub_regmap, reg, val);
> +}
> +
> +void max98927_wrap_update_bits(struct max98927_priv *max98927,
> + unsigned int reg, unsigned int mask, unsigned int val)
> +{
> + if (max98927->regmap)
> + regmap_update_bits(max98927->regmap, reg, mask, val);
> + if (max98927->sub_regmap)
> + regmap_update_bits(max98927->sub_regmap, reg, mask, val);
> +}
> +
> +static int max98927_reg_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol, unsigned int reg,
> + unsigned int mask, unsigned int shift)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + int data;
> +
> + regmap_read(max98927->regmap, reg, &data);
> + ucontrol->value.integer.value[0] =
> + (data & mask) >> shift;
> + return 0;
> +}
> +
> +static int max98927_reg_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol, unsigned int reg,
> + unsigned int mask, unsigned int shift)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + unsigned int sel = ucontrol->value.integer.value[0];
> +
> + max98927_wrap_update_bits(max98927, reg, mask, sel << shift);
> + dev_dbg(codec->dev, "%s: register 0x%02X, value 0x%02X\n",
> + __func__, reg, sel);
> + return 0;
> +}
> +
> +static int max98927_dai_set_fmt(struct snd_soc_dai *codec_dai,
> + unsigned int fmt)
> +{
> + struct snd_soc_codec *codec = codec_dai->codec;
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + unsigned int invert = 0;
> +
> + dev_dbg(codec->dev, "%s: fmt 0x%08X\n", __func__, fmt);
> + switch (fmt & SND_SOC_DAIFMT_MASTER_MASK) {
> + case SND_SOC_DAIFMT_CBS_CFS:
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_SLAVE);
> + break;
> + case SND_SOC_DAIFMT_CBM_CFM:
> + max98927->master = true;
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_MASTER);
> + break;
> + case SND_SOC_DAIFMT_CBS_CFM:
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_HYBRID);
> + default:
> + dev_err(codec->dev, "DAI clock mode unsupported");
> + return -EINVAL;
> + }
Please fill up the mask variable and apply in one round after the switch.
> +
> + switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
> + case SND_SOC_DAIFMT_NB_NF:
> + break;
> + case SND_SOC_DAIFMT_IB_NF:
> + invert = MAX98927_PCM_Mode_Config_PCM_BCLKEDGE;
> + break;
> + default:
> + dev_err(codec->dev, "DAI invert mode unsupported");
> + return -EINVAL;
> + }
> +
> + /* interface format */
> + switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
> + case SND_SOC_DAIFMT_I2S:
> + max98927->iface |= SND_SOC_DAIFMT_I2S;
> + max98927_wrap_update_bits(max98927,
> + MAX98927_PCM_Mode_Config,
> + max98927->iface, max98927->iface);
> + break;
> + case SND_SOC_DAIFMT_LEFT_J:
> + max98927->iface |= SND_SOC_DAIFMT_LEFT_J;
> + max98927_wrap_update_bits(max98927,
> + MAX98927_PCM_Mode_Config,
> + max98927->iface, max98927->iface);
> + break;
> + default:
> + return -EINVAL;
> + }
> +
Same here
> + /* pcm channel configuration */
> + if (max98927->iface & (SND_SOC_DAIFMT_I2S | SND_SOC_DAIFMT_LEFT_J)) {
> + max98927_wrapper_write(max98927,
> + MAX98927_PCM_Rx_Enables_A,
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH0_EN|
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH1_EN);
> + max98927_wrapper_write(max98927,
> + MAX98927_PCM_Tx_Enables_A,
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH0_EN|
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH1_EN);
> + }
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Mode_Config,
> + MAX98927_PCM_Mode_Config_PCM_BCLKEDGE, invert);
> + return 0;
> +}
> +
> +/* codec MCLK rate in master mode */
> +static const int rate_table[] = {
> + 5644800, 6000000, 6144000, 6500000,
> + 9600000, 11289600, 12000000, 12288000,
> + 13000000, 19200000,
> +};
> +
> +static int max98927_set_clock(struct max98927_priv *max98927,
> + struct snd_pcm_hw_params *params)
> +{
> + /* BCLK/LRCLK ratio calculation */
> + int blr_clk_ratio = params_channels(params) * max98927->ch_size;
> + int reg = MAX98927_PCM_Clock_setup;
> + int mask = MAX98927_PCM_Clock_setup_PCM_BSEL_Mask;
> + int value;
> +
> + if (max98927->master) {
> + int i;
> + /* match rate to closest value */
> + for (i = 0; i < ARRAY_SIZE(rate_table); i++) {
> + if (rate_table[i] >= max98927->sysclk)
> + break;
> + }
> + if (i == ARRAY_SIZE(rate_table)) {
> + pr_err("%s couldn't get the MCLK to match codec\n",
> + __func__);
> + return -EINVAL;
> + }
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Master_Mode,
> + MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_Mask,
> + i << MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_SHIFT);
> + }
some code style here
> +
> + switch (blr_clk_ratio) {
> + case 32:
> + value = 2;
> + break;
> + case 48:
> + value = 3;
> + break;
> + case 64:
> + value = 4;
> + break;
> + default:
> + return -EINVAL;
> + }
> + max98927_wrap_update_bits(max98927,
> + reg, mask, value);
> + return 0;
> +}
> +
ditto
> +static int max98927_dai_hw_params(struct snd_pcm_substream *substream,
> + struct snd_pcm_hw_params *params,
> + struct snd_soc_dai *dai)
> +{
> + struct snd_soc_codec *codec = dai->codec;
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + int sampling_rate = 0;
> +
> + /* pcm mode configuration */
> + switch (snd_pcm_format_width(params_format(params))) {
> + case 16:
> + max98927_wrap_update_bits(max98927,
> + MAX98927_PCM_Mode_Config,
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_16,
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_16);
> + max98927->ch_size = 16;
> + break;
> + case 24:
> + max98927_wrap_update_bits(max98927,
> + MAX98927_PCM_Mode_Config,
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_24,
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_24);
> + max98927->ch_size = 24;
> + break;
> + case 32:
> + max98927_wrap_update_bits(max98927,
> + MAX98927_PCM_Mode_Config,
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_32,
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_32);
> + max98927->ch_size = 32;
> + break;
> + default:
> + pr_err("%s: format unsupported %d",
> + __func__, params_format(params));
> + goto err;
> + }
Move update bits after switch. Can you update a new version?
Michael
> + dev_dbg(codec->dev, "%s: format supported %d",
> + __func__, params_format(params));
> +
> + /* sampling rate configuration */
> + switch (params_rate(params)) {
> + case 8000:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_8000;
> + break;
> + case 11025:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_11025;
> + break;
> + case 12000:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_12000;
> + break;
> + case 16000:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_16000;
> + break;
> + case 22050:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_22050;
> + break;
> + case 24000:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_24000;
> + break;
> + case 32000:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_32000;
> + break;
> + case 44100:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_44100;
> + break;
> + case 48000:
> + sampling_rate |=
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_48000;
> + break;
> + default:
> + pr_err("%s rate %d not supported\n",
> + __func__, params_rate(params));
> + goto err;
> + }
> + /* set DAI_SR to correct LRCLK frequency */
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_1,
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_Mask, sampling_rate);
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_2,
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_Mask, sampling_rate<<4);
> + max98927_wrap_update_bits(max98927, MAX98927_PCM_Sample_rate_setup_2,
> + MAX98927_PCM_Sample_rate_setup_2_IVADC_SR_Mask, sampling_rate);
> + return max98927_set_clock(max98927, params);
> +err:
> + return -EINVAL;
> +}
> +
> +#define MAX98927_RATES SNDRV_PCM_RATE_8000_48000
> +
> +#define MAX98927_FORMATS (SNDRV_PCM_FMTBIT_S16_LE | \
> + SNDRV_PCM_FMTBIT_S24_LE | SNDRV_PCM_FMTBIT_S32_LE)
> +
> +static int max98927_dai_set_sysclk(struct snd_soc_dai *dai,
> + int clk_id, unsigned int freq, int dir)
> +{
> + struct snd_soc_codec *codec = dai->codec;
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> + max98927->sysclk = freq;
> + return 0;
> +}
> +
> +static const struct snd_soc_dai_ops max98927_dai_ops = {
> + .set_sysclk = max98927_dai_set_sysclk,
> + .set_fmt = max98927_dai_set_fmt,
> + .hw_params = max98927_dai_hw_params,
> +};
> +
> +static void max98927_handle_pdata(struct snd_soc_codec *codec)
> +{
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + struct max98927_reg_default *regInfo;
> + int cfg_size = 0;
> + int x;
> +
> + if (max98927->regcfg != NULL)
> + cfg_size = max98927->regcfg_sz / sizeof(uint32_t);
> +
> + if (cfg_size <= 0) {
> + dev_dbg(codec->dev,
> + "Register configuration is not required.\n");
> + return;
> + }
> +
> + /* direct configuration from device tree */
> + for (x = 0; x < cfg_size; x += 3) {
> + regInfo = (struct max98927_reg_default *)&max98927->regcfg[x];
> + dev_info(codec->dev, "CH:%d, reg:0x%02x, value:0x%02x\n",
> + be32_to_cpu(regInfo->ch),
> + be32_to_cpu(regInfo->reg),
> + be32_to_cpu(regInfo->def));
> + if (be32_to_cpu(regInfo->ch) == PRI_MAX98927
> + && max98927->regmap)
> + regmap_write(max98927->regmap,
> + be32_to_cpu(regInfo->reg),
> + be32_to_cpu(regInfo->def));
> + else if (be32_to_cpu(regInfo->ch) == SEC_MAX98927
> + && max98927->sub_regmap)
> + regmap_write(max98927->sub_regmap,
> + be32_to_cpu(regInfo->reg),
> + be32_to_cpu(regInfo->def));
> + }
> +}
> +
> +static int max98927_dac_event(struct snd_soc_dapm_widget *w,
> + struct snd_kcontrol *kcontrol, int event)
> +{
> + struct snd_soc_codec *codec = snd_soc_dapm_to_codec(w->dapm);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> + switch (event) {
> + case SND_SOC_DAPM_POST_PMU:
> + max98927_wrap_update_bits(max98927,
> + MAX98927_AMP_enables, 1, 1);
> + /* enable the v and i for vi feedback */
> + max98927_wrap_update_bits(max98927,
> + MAX98927_Measurement_enables,
> + MAX98927_Measurement_enables_IVADC_V_EN,
> + MAX98927_Measurement_enables_IVADC_V_EN);
> + max98927_wrap_update_bits(max98927,
> + MAX98927_Measurement_enables,
> + MAX98927_Measurement_enables_IVADC_I_EN,
> + MAX98927_Measurement_enables_IVADC_I_EN);
> + max98927_wrap_update_bits(max98927,
> + MAX98927_Global_Enable, 1, 1);
> + break;
> + case SND_SOC_DAPM_POST_PMD:
> + max98927_wrap_update_bits(max98927,
> + MAX98927_Global_Enable, 1, 0);
> + max98927_wrap_update_bits(max98927,
> + MAX98927_AMP_enables, 1, 0);
> + /* disable the v and i for vi feedback */
> + max98927_wrap_update_bits(max98927,
> + MAX98927_Measurement_enables,
> + MAX98927_Measurement_enables_IVADC_V_EN,
> + 0);
> + max98927_wrap_update_bits(max98927,
> + MAX98927_Measurement_enables,
> + MAX98927_Measurement_enables_IVADC_I_EN,
> + 0);
> + break;
> + default:
> + return 0;
> + }
> + return 0;
> +}
> +
> +static const struct snd_soc_dapm_widget max98927_dapm_widgets[] = {
> + SND_SOC_DAPM_AIF_IN("DAI_OUT", "HiFi Playback", 0, SND_SOC_NOPM, 0, 0),
> + SND_SOC_DAPM_DAC_E("Amp Enable", "HiFi Playback", MAX98927_AMP_enables,
> + 0, 0, max98927_dac_event,
> + SND_SOC_DAPM_POST_PMU | SND_SOC_DAPM_POST_PMD),
> + SND_SOC_DAPM_OUTPUT("BE_OUT"),
> +};
> +
> +static DECLARE_TLV_DB_SCALE(max98927_spk_tlv, 300, 300, 0);
> +static DECLARE_TLV_DB_SCALE(max98927_digital_tlv, -1600, 25, 0);
> +
> +static int max98927_spk_gain_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> + ucontrol->value.integer.value[0] = max98927->spk_gain;
> + dev_dbg(codec->dev, "%s: spk_gain setting returned %d\n", __func__,
> + (int) ucontrol->value.integer.value[0]);
> + return 0;
> +}
> +
> +static int max98927_spk_gain_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + unsigned int sel = ucontrol->value.integer.value[0];
> +
> + if (sel < ((1 << MAX98927_Speaker_Gain_Width) - 1)) {
> + max98927_wrap_update_bits(max98927, MAX98927_Speaker_Gain,
> + MAX98927_Speaker_Gain_SPK_PCM_GAIN_Mask, sel);
> + max98927->spk_gain = sel;
> + }
> + return 0;
> +}
> +
> +static int max98927_digital_gain_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> +
> + ucontrol->value.integer.value[0] = max98927->digital_gain;
> + dev_dbg(codec->dev, "%s: spk_gain setting returned %d\n", __func__,
> + (int) ucontrol->value.integer.value[0]);
> + return 0;
> +}
> +
> +static int max98927_digital_gain_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + struct snd_soc_codec *codec = snd_kcontrol_chip(kcontrol);
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + unsigned int sel = ucontrol->value.integer.value[0];
> +
> + if (sel < ((1 << MAX98927_AMP_VOL_WIDTH) - 1)) {
> + max98927_wrap_update_bits(max98927, MAX98927_AMP_volume_control,
> + MAX98927_AMP_volume_control_AMP_VOL_Mask, sel);
> + max98927->digital_gain = sel;
> + }
> + return 0;
> +}
> +
> +static int max98927_boost_voltage_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol, MAX98927_Boost_Control_0,
> + MAX98927_Boost_Control_0_BST_VOUT_Mask, 0);
> +}
> +
> +static int max98927_boost_voltage_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol, MAX98927_Boost_Control_0,
> + MAX98927_Boost_Control_0_BST_VOUT_Mask, 0);
> +}
> +
> +static int max98927_amp_vol_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol, MAX98927_Boost_Control_0,
> + MAX98927_Boost_Control_0_BST_VOUT_Mask,
> + MAX98927_AMP_VOL_LOCATION_SHIFT);
> +}
> +
> +static int max98927_amp_dsp_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol, MAX98927_Brownout_enables,
> + MAX98927_Brownout_enables_AMP_DSP_EN, MAX98927_BDE_DSP_SHIFT);
> +}
> +
> +static int max98927_amp_dsp_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol, MAX98927_Brownout_enables,
> + MAX98927_Brownout_enables_AMP_DSP_EN, MAX98927_BDE_DSP_SHIFT);
> +}
> +
> +static int max98927_ramp_switch_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol, MAX98927_AMP_DSP_Config,
> + MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS,
> + MAX98927_SPK_RMP_EN_SHIFT);
> +}
> +static int max98927_ramp_switch_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol, MAX98927_AMP_DSP_Config,
> + MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS,
> + MAX98927_SPK_RMP_EN_SHIFT);
> +}
> +
> +static int max98927_dre_en_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol, MAX98927_DRE_Control,
> + MAX98927_DRE_Control_DRE_EN, 0);
> +}
> +static int max98927_dre_en_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol, MAX98927_DRE_Control,
> + MAX98927_DRE_Control_DRE_EN, 0);
> +}
> +static int max98927_amp_vol_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol,
> + MAX98927_AMP_volume_control,
> + MAX98927_AMP_volume_control_AMP_VOL_SEL,
> + MAX98927_AMP_VOL_LOCATION_SHIFT);
> +}
> +static int max98927_spk_src_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol,
> + MAX98927_Speaker_source_select,
> + MAX98927_Speaker_source_select_SPK_SOURCE_Mask, 0);
> +}
> +
> +static int max98927_spk_src_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol,
> + MAX98927_Speaker_source_select,
> + MAX98927_Speaker_source_select_SPK_SOURCE_Mask, 0);
> +}
> +
> +static int max98927_mono_out_get(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_get(kcontrol, ucontrol,
> + MAX98927_PCM_to_speaker_monomix_A,
> + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask,
> + MAX98927_PCM_to_speaker_monomix_A_SHIFT);
> +}
> +
> +static int max98927_mono_out_put(struct snd_kcontrol *kcontrol,
> + struct snd_ctl_elem_value *ucontrol)
> +{
> + return max98927_reg_put(kcontrol, ucontrol,
> + MAX98927_PCM_to_speaker_monomix_A,
> + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask,
> + MAX98927_PCM_to_speaker_monomix_A_SHIFT);
> +}
> +
> +static bool max98927_readable_register(struct device *dev, unsigned int reg)
> +{
> + switch (reg) {
> + case 0x0001 ... 0x0028:
> + case 0x002B ... 0x004E:
> + case 0x0051 ... 0x0055:
> + case 0x005A ... 0x0061:
> + case 0x0072 ... 0x0087:
> + case 0x00FF:
> + case 0x0100:
> + case 0x01FF:
> + return true;
> + }
> + return false;
> +};
> +
> +static const char * const max98927_boost_voltage_text[] = {
> + "6.5V", "6.625V", "6.75V", "6.875V", "7V", "7.125V", "7.25V", "7.375V",
> + "7.5V", "7.625V", "7.75V", "7.875V", "8V", "8.125V", "8.25V", "8.375V",
> + "8.5V", "8.625V", "8.75V", "8.875V", "9V", "9.125V", "9.25V", "9.375V",
> + "9.5V", "9.625V", "9.75V", "9.875V", "10V"
> +};
> +
> +static const char * const max98927_speaker_source_text[] = {
> + "i2s", "reserved", "tone", "pdm"
> +};
> +
> +static const char * const max98927_monomix_output_text[] = {
> + "ch_0", "ch_1", "ch_1_2_div"
> +};
> +
> +static const struct soc_enum max98927_enum[] = {
> + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_monomix_output_text),
> + max98927_monomix_output_text),
> + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_speaker_source_text),
> + max98927_speaker_source_text),
> + SOC_ENUM_SINGLE_EXT(ARRAY_SIZE(max98927_boost_voltage_text),
> + max98927_boost_voltage_text),
> +};
> +
> +static const struct snd_kcontrol_new max98927_snd_controls[] = {
> + SOC_SINGLE_EXT_TLV("Speaker Volume", MAX98927_Speaker_Gain,
> + 0, (1<<MAX98927_Speaker_Gain_Width)-1, 0,
> + max98927_spk_gain_get, max98927_spk_gain_put,
> + max98927_spk_tlv),
> + SOC_SINGLE_EXT_TLV("Digital Gain", MAX98927_AMP_volume_control,
> + 0, (1<<MAX98927_AMP_VOL_WIDTH)-1, 0,
> + max98927_digital_gain_get, max98927_digital_gain_put,
> + max98927_digital_tlv),
> + SOC_SINGLE_EXT("Amp DSP Enable", MAX98927_Brownout_enables,
> + MAX98927_BDE_DSP_SHIFT, 1, 0,
> + max98927_amp_dsp_get, max98927_amp_dsp_put),
> + SOC_SINGLE_EXT("Ramp Switch", MAX98927_AMP_DSP_Config,
> + MAX98927_SPK_RMP_EN_SHIFT, 1, 1,
> + max98927_ramp_switch_get, max98927_ramp_switch_put),
> + SOC_SINGLE_EXT("DRE EN", MAX98927_DRE_Control,
> + MAX98927_DRE_Control_DRE_SHIFT, 1, 0,
> + max98927_dre_en_get, max98927_dre_en_put),
> + SOC_SINGLE_EXT("Amp Volume Location", MAX98927_AMP_volume_control,
> + MAX98927_AMP_VOL_LOCATION_SHIFT, 1, 0,
> + max98927_amp_vol_get, max98927_amp_vol_put),
> +
> + SOC_ENUM_EXT("Boost Output Voltage", max98927_enum[2],
> + max98927_boost_voltage_get, max98927_boost_voltage_put),
> + SOC_ENUM_EXT("Speaker Source", max98927_enum[1],
> + max98927_spk_src_get, max98927_spk_src_put),
> + SOC_ENUM_EXT("Monomix Output", max98927_enum[0],
> + max98927_mono_out_get, max98927_mono_out_put),
> +};
> +
> +static const struct snd_soc_dapm_route max98927_audio_map[] = {
> + {"BE_OUT", NULL, "Amp Enable"},
> +};
> +
> +static struct snd_soc_dai_driver max98927_dai[] = {
> + {
> + .name = "max98927-aif1",
> + .playback = {
> + .stream_name = "HiFi Playback",
> + .channels_min = 1,
> + .channels_max = 2,
> + .rates = MAX98927_RATES,
> + .formats = MAX98927_FORMATS,
> + },
> + .capture = {
> + .stream_name = "HiFi Capture",
> + .channels_min = 1,
> + .channels_max = 2,
> + .rates = MAX98927_RATES,
> + .formats = MAX98927_FORMATS,
> + },
> + .ops = &max98927_dai_ops,
> + }
> +};
> +
> +static int max98927_probe(struct snd_soc_codec *codec)
> +{
> + struct max98927_priv *max98927 = snd_soc_codec_get_drvdata(codec);
> + int ret = 0, reg = 0, i;
> +
> + max98927->codec = codec;
> + codec->control_data = max98927->regmap;
> + codec->cache_bypass = 1;
> +
> + /* Software Reset */
> + max98927_wrapper_write(max98927,
> + MAX98927_Software_Reset, MAX98927_Software_Reset_RST);
> +
> + /* Check Revision ID for the primary MAX98927*/
> + ret = regmap_read(max98927->regmap, MAX98927_REV_ID, ®);
> + if (ret < 0)
> + dev_err(codec->dev,
> + "Failed to read: 0x%02X\n", MAX98927_REV_ID);
> + else
> + dev_info(codec->dev,
> + "MAX98927 revisionID: 0x%02X\n", reg);
> +
> + /* Check Revision ID for the secondary MAX98927*/
> + if (max98927->sub_regmap) {
> + ret = regmap_read(max98927->sub_regmap, MAX98927_REV_ID, ®);
> + if (ret < 0)
> + dev_err(codec->dev,
> + "Failed to read: 0x%02X from secodnary device\n"
> + , MAX98927_REV_ID);
> + else
> + dev_info(codec->dev,
> + "Secondary device revisionID: 0x%02X\n", reg);
> + }
> +
> + /* Register initialization */
> + for (i = 0; i < sizeof(max98927_reg_map)/
> + sizeof(max98927_reg_map[0]); i++)
> + max98927_wrapper_write(max98927,
> + max98927_reg_map[i].reg,
> + max98927_reg_map[i].def);
> +
> + if (max98927->regmap)
> + regmap_write(max98927->regmap,
> + MAX98927_PCM_Tx_Channel_Sources_A,
> + (max98927->i_l_slot
> + <<MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT|
> + max98927->v_l_slot)&0xFF);
> + if (max98927->sub_regmap)
> + regmap_write(max98927->sub_regmap,
> + MAX98927_PCM_Tx_Channel_Sources_A,
> + (max98927->i_r_slot
> + <<MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT|
> + max98927->v_r_slot)&0xFF);
> +
> + /* Set interleave mode */
> + if (max98927->interleave_mode)
> + max98927_wrap_update_bits(max98927,
> + MAX98927_PCM_Tx_Channel_Sources_B,
> + MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask,
> + MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask);
> +
> + max98927_handle_pdata(codec);
> +
> + return ret;
> +}
> +
> +static const struct snd_soc_codec_driver soc_codec_dev_max98927 = {
> + .probe = max98927_probe,
> + .dapm_routes = max98927_audio_map,
> + .num_dapm_routes = ARRAY_SIZE(max98927_audio_map),
> + .dapm_widgets = max98927_dapm_widgets,
> + .num_dapm_widgets = ARRAY_SIZE(max98927_dapm_widgets),
> + .controls = max98927_snd_controls,
> + .num_controls = ARRAY_SIZE(max98927_snd_controls),
> +};
> +
> +static const struct regmap_config max98927_regmap = {
> + .reg_bits = 16,
> + .val_bits = 8,
> + .max_register = MAX98927_REV_ID,
> + .reg_defaults = max98927_reg_map,
> + .num_reg_defaults = ARRAY_SIZE(max98927_reg_map),
> + .readable_reg = max98927_readable_register,
> + .cache_type = REGCACHE_RBTREE,
> +};
> +
> +static struct i2c_board_info max98927_i2c_sub_board[] = {
> + {
> + I2C_BOARD_INFO("max98927_sub", 0x39),
> + }
> +};
> +
> +static struct i2c_driver max98927_i2c_sub_driver = {
> + .driver = {
> + .name = "max98927_sub",
> + .owner = THIS_MODULE,
> + },
> +};
> +
> +struct i2c_client *max98927_add_sub_device(int bus_id, int slave_addr)
> +{
> + struct i2c_client *i2c = NULL;
> + struct i2c_adapter *adapter;
> +
> + max98927_i2c_sub_board[0].addr = slave_addr;
> +
> + adapter = i2c_get_adapter(bus_id);
> + if (adapter) {
> + i2c = i2c_new_device(adapter, max98927_i2c_sub_board);
> + if (i2c)
> + i2c->dev.driver = &max98927_i2c_sub_driver.driver;
> + }
> +
> + return i2c;
> +}
> +
> +int probe_common(struct i2c_client *i2c, struct max98927_priv *max98927)
> +{
> + int ret = 0, value;
> +
> + if (!of_property_read_u32(i2c->dev.of_node, "vmon-l-slot", &value))
> + max98927->v_l_slot = value & 0xF;
> + else
> + max98927->v_l_slot = 0;
> + if (!of_property_read_u32(i2c->dev.of_node, "imon-l-slot", &value))
> + max98927->i_l_slot = value & 0xF;
> + else
> + max98927->i_l_slot = 1;
> + if (!of_property_read_u32(i2c->dev.of_node, "vmon-r-slot", &value))
> + max98927->v_r_slot = value & 0xF;
> + else
> + max98927->v_r_slot = 2;
> + if (!of_property_read_u32(i2c->dev.of_node, "imon-r-slot", &value))
> + max98927->i_r_slot = value & 0xF;
> + else
> + max98927->i_r_slot = 3;
> +
> + ret = snd_soc_register_codec(&i2c->dev, &soc_codec_dev_max98927,
> + max98927_dai, ARRAY_SIZE(max98927_dai));
> + if (ret < 0)
> + dev_err(&i2c->dev,
> + "Failed to register codec: %d\n", ret);
> + return ret;
> +}
> +
> +static int max98927_i2c_probe(struct i2c_client *i2c,
> + const struct i2c_device_id *id)
> +{
> +
> + int ret = 0, value;
> + struct max98927_priv *max98927 = NULL;
> +
> + max98927 = devm_kzalloc(&i2c->dev,
> + sizeof(*max98927), GFP_KERNEL);
> +
> + if (!max98927) {
> + ret = -ENOMEM;
> + goto err;
> + }
> + i2c_set_clientdata(i2c, max98927);
> +
> + /* update interleave mode info */
> + if (!of_property_read_u32(i2c->dev.of_node,
> + "interleave_mode", &value)) {
> + if (value > 0)
> + max98927->interleave_mode = 1;
> + else
> + max98927->interleave_mode = 0;
> + } else
> + max98927->interleave_mode = 0;
> +
> + /* update direct configuration info */
> + max98927->regcfg = of_get_property(i2c->dev.of_node,
> + "maxim,regcfg", &max98927->regcfg_sz);
> +
> + /* check for secondary MAX98927 */
> + ret = of_property_read_u32(i2c->dev.of_node,
> + "maxim,sub_reg", &max98927->sub_reg);
> + if (ret) {
> + dev_err(&i2c->dev, "Sub-device slave address was not found.\n");
> + max98927->sub_reg = -1;
> + }
> + ret = of_property_read_u32(i2c->dev.of_node,
> + "maxim,sub_bus", &max98927->sub_bus);
> + if (ret) {
> + dev_err(&i2c->dev, "Sub-device bus information was not found.\n");
> + max98927->sub_bus = i2c->adapter->nr;
> + }
> +
> + /* regmap initialization for primary device */
> + max98927->regmap
> + = devm_regmap_init_i2c(i2c, &max98927_regmap);
> + if (IS_ERR(max98927->regmap)) {
> + ret = PTR_ERR(max98927->regmap);
> + dev_err(&i2c->dev,
> + "Failed to allocate regmap: %d\n", ret);
> + goto err;
> + }
> +
> + /* regmap initialization for secondary device */
> + if (max98927->sub_reg > 0) {
> + max98927->sub_i2c = max98927_add_sub_device(max98927->sub_bus,
> + max98927->sub_reg);
> + if (IS_ERR(max98927->sub_i2c)) {
> + dev_err(&max98927->sub_i2c->dev,
> + "Second MAX98927 was not found\n");
> + ret = PTR_ERR(max98927->regmap);
> + goto err;
> + } else {
> + max98927->sub_regmap = regmap_init_i2c(
> + max98927->sub_i2c, &max98927_regmap);
> + if (IS_ERR(max98927->sub_regmap)) {
> + ret = PTR_ERR(max98927->sub_regmap);
> + dev_err(&max98927->sub_i2c->dev,
> + "Failed to allocate sub_regmap: %d\n",
> + ret);
> + goto err;
> + }
> + }
> + }
> +
> + /* codec registeration */
> + ret = probe_common(i2c, max98927);
> +
> + return ret;
> +
> +err:
> + if (max98927)
> + devm_kfree(&i2c->dev, max98927);
> + return ret;
> +}
> +
> +static int max98927_i2c_remove(struct i2c_client *client)
> +{
> + snd_soc_unregister_codec(&client->dev);
> + return 0;
> +}
> +
> +static const struct i2c_device_id max98927_i2c_id[] = {
> + { "max98927", 0},
> + { },
> +};
> +
> +MODULE_DEVICE_TABLE(i2c, max98927_i2c_id);
> +
> +static const struct of_device_id max98927_of_match[] = {
> + { .compatible = "maxim,max98927", },
> + { }
> +};
> +MODULE_DEVICE_TABLE(of, max98927_of_match);
> +
> +static struct i2c_driver max98927_i2c_driver = {
> + .driver = {
> + .name = "max98927",
> + .owner = THIS_MODULE,
> + .of_match_table = of_match_ptr(max98927_of_match),
> + .pm = NULL,
> + },
> + .probe = max98927_i2c_probe,
> + .remove = max98927_i2c_remove,
> + .id_table = max98927_i2c_id,
> +};
> +
> +module_i2c_driver(max98927_i2c_driver)
> +
> +MODULE_DESCRIPTION("ALSA SoC MAX98927 driver");
> +MODULE_AUTHOR("Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>");
> +MODULE_LICENSE("GPL");
> diff --git a/sound/soc/codecs/max98927.h b/sound/soc/codecs/max98927.h
> new file mode 100755
> index 0000000..2305185
> --- /dev/null
> +++ b/sound/soc/codecs/max98927.h
> @@ -0,0 +1,1253 @@
> +/*
> + * max98927.c -- MAX98927 ALSA Soc Audio driver
> + *
> + * Copyright 2008-11 Wolfson Microelectronics PLC.
> + * Author: Ryan Lee <ryans.lee-zxKO94PEStzToO697jQleEEOCMrvLtNR@public.gmane.org>
> + *
> + * This program is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License as published by the
> + * Free Software Foundation; either version 2 of the License, or (at your
> + * option) any later version.
> + *
> + */
> +#ifndef __MAX98927_REGISTERDEFS_H
> +#define __MAX98927_REGISTERDEFS_H
> +#ifdef CONFIG_SND_SOC_MAXIM_DSM
> +#include <sound/maxim_dsm.h>
> +#endif /* CONFIG_SND_SOC_MAXIM_DSM */
> +
> +enum {
> + PRI_MAX98927 = 0,
> + SEC_MAX98927 = 1,
> + MAX_DEV_ID_MAX98927,
> +} MAX98927deviceID;
> +
> +enum {
> + /*Interrupt Raw 1 (Address 0x0001)*/
> + MAX98927_Interrupt_Raw_1 = 0x0001,
> + MAX98927_Interrupt_Raw_1_BDE_ACTIVE_END_RAW = (0x1 << 0),
> + MAX98927_Interrupt_Raw_1_BDE_ACTIVE_BGN_RAW = (0x1 << 1),
> + MAX98927_Interrupt_Raw_1_BDE_LEVEL_CHANGE_RAW = (0x1 << 2),
> + MAX98927_Interrupt_Raw_1_BDE_L8_RAW = (0x1 << 3),
> + MAX98927_Interrupt_Raw_1_THERMWARN_END_RAW = (0x1 << 4),
> + MAX98927_Interrupt_Raw_1_THERMWARN_START_RAW = (0x1 << 5),
> + MAX98927_Interrupt_Raw_1_THERMSHDN_END_RAW = (0x1 << 6),
> + MAX98927_Interrupt_Raw_1_THERMSHDN_START_RAW = (0x1 << 7),
> +
> + /* Interrupt Raw 2 (Address 0x0002)*/
> + MAX98927_Interrupt_Raw_2 = 0x0002,
> + MAX98927_Interrupt_Raw_2_WATCHDOGWARN_RAW = (0x1 << 0),
> + MAX98927_Interrupt_Raw_2_WATCHDOGFAIL_RAW = (0x1 << 1),
> + MAX98927_Interrupt_Raw_2_BOOSTCURRLIM_RAW = (0x1 << 2),
> + MAX98927_Interrupt_Raw_2_CLKSTOP_RAW = (0x1 << 3),
> + MAX98927_Interrupt_Raw_2_CLKSTART_RAW = (0x1 << 4),
> + MAX98927_Interrupt_Raw_2_MEASADC_END_RAW = (0x1 << 5),
> + MAX98927_Interrupt_Raw_2_PWRDN_DONE_RAW = (0x1 << 6),
> + MAX98927_Interrupt_Raw_2_PWRUP_DONE_RAW = (0x1 << 7),
> +
> + /* Interrupt Raw 3 (Address 0x0003)*/
> + MAX98927_Interrupt_Raw_3 = 0x0003,
> + MAX98927_Interrupt_Raw_3_PWRUP_FAIL_RAW = (0x1 << 0),
> + MAX98927_Interrupt_Raw_3_AUTH_DONE_RAW = (0x1 << 1),
> + MAX98927_Interrupt_Raw_3_SPK_OVC_RAW = (0x1 << 2),
> + MAX98927_Interrupt_Raw_3_BST_UVLO_RAW = (0x1 << 3),
> +
> + /* Interrupt State 1 (Address 0x0004)*/
> + MAX98927_Interrupt_State_1 = 0x0004,
> + MAX98927_Interrupt_State_1_BDE_ACTIVE_END_STATE = (0x1 << 0),
> + MAX98927_Interrupt_State_1_BDE_ACTIVE_BGN_STATE = (0x1 << 1),
> + MAX98927_Interrupt_State_1_BDE_LEVEL_CHANGE_STATE = (0x1 << 2),
> + MAX98927_Interrupt_State_1_BDE_L8_STATE = (0x1 << 3),
> + MAX98927_Interrupt_State_1_THERMWARN_END_STATE = (0x1 << 4),
> + MAX98927_Interrupt_State_1_THERMWARN_START_STATE = (0x1 << 5),
> + MAX98927_Interrupt_State_1_THERMSHDN_END_STATE = (0x1 << 6),
> + MAX98927_Interrupt_State_1_THERMSHDN_START_STATE = (0x1 << 7),
> +
> + /* Interrupt State 2 (Address 0x0005)*/
> + MAX98927_Interrupt_State_2 = 0x0005,
> + MAX98927_Interrupt_State_2_WATCHDOGWARN_STATE = (0x1 << 0),
> + MAX98927_Interrupt_State_2_WATCHDOGFAIL_STATE = (0x1 << 1),
> + MAX98927_Interrupt_State_2_BOOSTCURRLIM_STATE = (0x1 << 2),
> + MAX98927_Interrupt_State_2_CLKSTOP_STATE = (0x1 << 3),
> + MAX98927_Interrupt_State_2_CLKSTART_STATE = (0x1 << 4),
> + MAX98927_Interrupt_State_2_MEASADC_END_STATE = (0x1 << 5),
> + MAX98927_Interrupt_State_2_PWRDN_DONE_STATE = (0x1 << 6),
> + MAX98927_Interrupt_State_2_PWRUP_DONE_STATE = (0x1 << 7),
> +
> + /* Interrupt State 3 (Address 0x0006)*/
> + MAX98927_Interrupt_State_3 = 0x0006,
> + MAX98927_Interrupt_State_3_PWRUP_FAIL_STATE = (0x1 << 0),
> + MAX98927_Interrupt_State_3_AUTH_DONE_STATE = (0x1 << 1),
> + MAX98927_Interrupt_State_3_SPK_OVC_STATE = (0x1 << 2),
> + MAX98927_Interrupt_State_3_BST_UVLO_STATE = (0x1 << 3),
> +
> + /* Interrupt Flag 1 (Address 0x0007)*/
> + MAX98927_Interrupt_Flag_1 = 0x0007,
> + MAX98927_Interrupt_Flag_1_BDE_ACTIVE_END_FLAG = (0x1 << 0),
> + MAX98927_Interrupt_Flag_1_BDE_ACTIVE_BGN_FLAG = (0x1 << 1),
> + MAX98927_Interrupt_Flag_1_BDE_LEVEL_CHANGE_FLAG = (0x1 << 2),
> + MAX98927_Interrupt_Flag_1_BDE_L8_FLAG = (0x1 << 3),
> + MAX98927_Interrupt_Flag_1_THERMWARN_END_FLAG = (0x1 << 4),
> + MAX98927_Interrupt_Flag_1_THERMWARN_START_FLAG = (0x1 << 5),
> + MAX98927_Interrupt_Flag_1_THERMSHDN_END_FLAG = (0x1 << 6),
> + MAX98927_Interrupt_Flag_1_THERMSHDN_START_FLAG = (0x1 << 7),
> +
> + /* Interrupt Flag 2 (Address 0x0008)*/
> + MAX98927_Interrupt_Flag_2 = 0x0008,
> + MAX98927_Interrupt_Flag_2_WATCHDOGWARN_FLAG = (0x1 << 0),
> + MAX98927_Interrupt_Flag_2_WATCHDOGFAIL_FLAG = (0x1 << 1),
> + MAX98927_Interrupt_Flag_2_BOOSTCURRLIM_FLAG = (0x1 << 2),
> + MAX98927_Interrupt_Flag_2_CLKSTOP_FLAG = (0x1 << 3),
> + MAX98927_Interrupt_Flag_2_CLKSTART_FLAG = (0x1 << 4),
> + MAX98927_Interrupt_Flag_2_MEASADC_END_FLAG = (0x1 << 5),
> + MAX98927_Interrupt_Flag_2_PWRDN_DONE_FLAG = (0x1 << 6),
> + MAX98927_Interrupt_Flag_2_PWRUP_DONE_FLAG = (0x1 << 7),
> +
> + /* Interrupt Flag 3 (Address 0x0009)*/
> + MAX98927_Interrupt_Flag_3 = 0x0009,
> + MAX98927_Interrupt_Flag_3_PWRUP_FAIL_FLAG = (0x1 << 0),
> + MAX98927_Interrupt_Flag_3_AUTH_DONE_FLAG = (0x1 << 1),
> + MAX98927_Interrupt_Flag_3_SPK_OVC_FLAG = (0x1 << 2),
> + MAX98927_Interrupt_Flag_3_BST_UVLO_FLAG = (0x1 << 3),
> +
> + /* Interrupt Enable 1 (Address 0x000a)*/
> + MAX98927_Interrupt_Enable_1 = 0x000a,
> + MAX98927_Interrupt_Enable_1_BDE_ACTIVE_END_EN = (0x1 << 0),
> + MAX98927_Interrupt_Enable_1_BDE_ACTIVE_BGN_EN = (0x1 << 1),
> + MAX98927_Interrupt_Enable_1_BDE_LEVEL_CHANGE_EN = (0x1 << 2),
> + MAX98927_Interrupt_Enable_1_BDE_L8_EN = (0x1 << 3),
> + MAX98927_Interrupt_Enable_1_THERMWARN_END_EN = (0x1 << 4),
> + MAX98927_Interrupt_Enable_1_THERMWARN_START_EN = (0x1 << 5),
> + MAX98927_Interrupt_Enable_1_THERMSHDN_END_EN = (0x1 << 6),
> + MAX98927_Interrupt_Enable_1_THERMSHDN_START_EN = (0x1 << 7),
> +
> + /* Interrupt Enable 2 (Address 0x000b)*/
> + MAX98927_Interrupt_Enable_2 = 0x000b,
> + MAX98927_Interrupt_Enable_2_WATCHDOGWARN_EN = (0x1 << 0),
> + MAX98927_Interrupt_Enable_2_WATCHDOGFAIL_EN = (0x1 << 1),
> + MAX98927_Interrupt_Enable_2_BOOSTCURRLIM_EN = (0x1 << 2),
> + MAX98927_Interrupt_Enable_2_CLKSTOP_EN = (0x1 << 3),
> + MAX98927_Interrupt_Enable_2_CLKSTART_EN = (0x1 << 4),
> + MAX98927_Interrupt_Enable_2_MEASADC_END_EN = (0x1 << 5),
> + MAX98927_Interrupt_Enable_2_PWRDN_DONE_EN = (0x1 << 6),
> + MAX98927_Interrupt_Enable_2_PWRUP_DONE_EN = (0x1 << 7),
> +
> + /* Interrupt Enable 3 (Address 0x000c)*/
> + MAX98927_Interrupt_Enable_3 = 0x000c,
> + MAX98927_Interrupt_Enable_3_PWRUP_FAIL_EN = (0x1 << 0),
> + MAX98927_Interrupt_Enable_3_AUTH_DONE_EN = (0x1 << 1),
> + MAX98927_Interrupt_Enable_3_SPK_OVC_EN = (0x1 << 2),
> + MAX98927_Interrupt_Enable_3_BST_UVLO_EN = (0x1 << 3),
> +
> + /* Interrupt Flag Clear 1 (Address 0x000d)*/
> + MAX98927_Interrupt_Flag_Clear_1 = 0x000d,
> + MAX98927_Interrupt_Flag_Clear_1_BDE_ACTIVE_END_CLR = (0x1 << 0),
> + MAX98927_Interrupt_Flag_Clear_1_BDE_ACTIVE_BGN_CLR = (0x1 << 1),
> + MAX98927_Interrupt_Flag_Clear_1_BDE_LEVEL_CHANGE_CLR = (0x1 << 2),
> + MAX98927_Interrupt_Flag_Clear_1_BDE_L8_CLR = (0x1 << 3),
> + MAX98927_Interrupt_Flag_Clear_1_THERMWARN_END_CLR = (0x1 << 4),
> + MAX98927_Interrupt_Flag_Clear_1_THERMWARN_START_CLR = (0x1 << 5),
> + MAX98927_Interrupt_Flag_Clear_1_THERMSHDN_END_CLR = (0x1 << 6),
> + MAX98927_Interrupt_Flag_Clear_1_THERMSHDN_START_CLR = (0x1 << 7),
> +
> + /* Interrupt Flag Clear 2 (Address 0x000e)*/
> + MAX98927_Interrupt_Flag_Clear_2 = 0x000e,
> + MAX98927_Interrupt_Flag_Clear_2_WATCHDOGWARN_CLR = (0x1 << 0),
> + MAX98927_Interrupt_Flag_Clear_2_WATCHDOGFAIL_CLR = (0x1 << 1),
> + MAX98927_Interrupt_Flag_Clear_2_BOOSTCURRLIM_CLR = (0x1 << 2),
> + MAX98927_Interrupt_Flag_Clear_2_CLKSTOP_CLR = (0x1 << 3),
> + MAX98927_Interrupt_Flag_Clear_2_CLKSTART_CLR = (0x1 << 4),
> + MAX98927_Interrupt_Flag_Clear_2_MEASADC_END_CLR = (0x1 << 5),
> + MAX98927_Interrupt_Flag_Clear_2_PWRDN_DONE_CLR = (0x1 << 6),
> + MAX98927_Interrupt_Flag_Clear_2_PWRUP_DONE_CLR = (0x1 << 7),
> +
> + /* Interrupt Flag Clear 3 (Address 0x000f)*/
> + MAX98927_Interrupt_Flag_Clear_3 = 0x000f,
> + MAX98927_Interrupt_Flag_Clear_3_PWRUP_FAIL_CLR = (0x1 << 0),
> + MAX98927_Interrupt_Flag_Clear_3_AUTH_DONE_CLR = (0x1 << 1),
> + MAX98927_Interrupt_Flag_Clear_3_SPK_OVC_CLR = (0x1 << 2),
> + MAX98927_Interrupt_Flag_Clear_3_BST_UVLO_CLR = (0x1 << 3),
> +
> + /* IRQ Control (Address 0x0010)*/
> + MAX98927_IRQ_Control = 0x0010,
> + MAX98927_IRQ_Control_IRQ_EN = (0x1 << 0),
> + MAX98927_IRQ_Control_IRQ_POL = (0x1 << 1),
> + MAX98927_IRQ_Control_IRQ_MODE = (0x1 << 2),
> +
> + /* Clock monitor enable (Address 0x0011)*/
> + MAX98927_Clock_monitor_enable = 0x0011,
> + MAX98927_Clock_monitor_enable_CMON_ENA = (0x1 << 0),
> + MAX98927_Clock_monitor_enable_CMON_AUTORESTART_ENA = (0x1 << 1),
> +
> + /* Watchdog Control (Address 0x0012)*/
> + MAX98927_Watchdog_Control = 0x0012,
> + MAX98927_Watchdog_Control_WDT_ENA = (0x1 << 0),
> + MAX98927_Watchdog_Control_WDT_MODE = (0x1 << 1),
> + MAX98927_Watchdog_Control_WDT_TO_SEL_Mask = (0x3 << 2),
> + MAX98927_Watchdog_Control_WDT_TO_SEL_5 = (0x0 << 2),
> + MAX98927_Watchdog_Control_WDT_TO_SEL_10 = (0x1 << 2),
> + MAX98927_Watchdog_Control_WDT_TO_SEL_35 = (0x2 << 2),
> + MAX98927_Watchdog_Control_WDT_TO_SEL_50 = (0x3 << 2),
> + MAX98927_Watchdog_Control_WDT_HW_SOURCE = (0x1 << 4),
> +
> + /* Watchdog SW Reset (Address 0x0013)*/
> + MAX98927_Watchdog_SW_Reset = 0x0013,
> + MAX98927_Watchdog_SW_Reset_WDT_SW_RST_Mask = (0xff << 0),
> +
> + /* Meas ADC Thermal Warning Threshhold (Address 0x0014)*/
> + MAX98927_Meas_ADC_TW_Threshhold = 0x0014,
> + MAX98927_Meas_ADC_TW_Threshhold_MEAS_ADC_WARN_THRESH_Mask
> + = (0xff << 0),
> +
> + /* Meas ADC Thermal Shutdown Threshhold (Address 0x0015)*/
> + MAX98927_Meas_ADC_TS_Threshhold = 0x0015,
> + MAX98927_Meas_ADC_TS_Threshhold_MEAS_ADC_SHDN_THRESH_Mask
> + = (0xff << 0),
> +
> + /* Meas ADC Thermal Hysteresis (Address 0x0016)*/
> + MAX98927_Meas_ADC_Thermal_Hysteresis = 0x0016,
> + MAX98927_Meas_ADC_TH_MEAS_ADC_THERM_HYST_Mask = (0x1f << 0),
> +
> + /* Pin Config (Address 0x0017)*/
> + MAX98927_Pin_Config = 0x0017,
> + MAX98927_Pin_Config_DOUT_DRV_Mask = (0x3 << 0),
> + MAX98927_Pin_Config_DOUT_DRV_01 = (0x0 << 0),
> + MAX98927_Pin_Config_DOUT_DRV_11 = (0x2 << 0),
> + MAX98927_Pin_Config_BCLK_DRV_Mask = (0x3 << 2),
> + MAX98927_Pin_Config_BCLK_DRV_01 = (0x0 << 2),
> + MAX98927_Pin_Config_BCLK_DRV_11 = (0x2 << 2),
> + MAX98927_Pin_Config_LRCLK_DRV_Mask = (0x3 << 4),
> + MAX98927_Pin_Config_LRCLK_DRV_01 = (0x0 << 4),
> + MAX98927_Pin_Config_LRCLK_DRV_11 = (0x2 << 4),
> + MAX98927_Pin_Config_ICC_DRV_Mask = (0x3 << 6),
> + MAX98927_Pin_Config_ICC_DRV_01 = (0x0 << 6),
> + MAX98927_Pin_Config_ICC_DRV_11 = (0x2 << 6),
> +
> + /* PCM Rx Enables A (Address 0x0018)*/
> + MAX98927_PCM_Rx_Enables_A = 0x0018,
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH0_EN = (0x1 << 0),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH1_EN = (0x1 << 1),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH2_EN = (0x1 << 2),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH3_EN = (0x1 << 3),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH4_EN = (0x1 << 4),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH5_EN = (0x1 << 5),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH6_EN = (0x1 << 6),
> + MAX98927_PCM_Rx_Enables_A_PCM_RX_CH7_EN = (0x1 << 7),
> +
> + /* PCM Rx Enables B (Address 0x0019)*/
> + MAX98927_PCM_Rx_Enables_B = 0x0019,
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH8_EN = (0x1 << 0),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH9_EN = (0x1 << 1),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH10_EN = (0x1 << 2),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH11_EN = (0x1 << 3),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH12_EN = (0x1 << 4),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH13_EN = (0x1 << 5),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH14_EN = (0x1 << 6),
> + MAX98927_PCM_Rx_Enables_B_PCM_RX_CH15_EN = (0x1 << 7),
> +
> + /* PCM Tx Enables A (Address 0x001a)*/
> + MAX98927_PCM_Tx_Enables_A = 0x001a,
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH0_EN = (0x1 << 0),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH1_EN = (0x1 << 1),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH2_EN = (0x1 << 2),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH3_EN = (0x1 << 3),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH4_EN = (0x1 << 4),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH5_EN = (0x1 << 5),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH6_EN = (0x1 << 6),
> + MAX98927_PCM_Tx_Enables_A_PCM_TX_CH7_EN = (0x1 << 7),
> +
> + /* PCM Tx Enables B (Address 0x001b)*/
> + MAX98927_PCM_Tx_Enables_B = 0x001b,
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH8_EN = (0x1 << 0),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH9_EN = (0x1 << 1),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH10_EN = (0x1 << 2),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH11_EN = (0x1 << 3),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH12_EN = (0x1 << 4),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH13_EN = (0x1 << 5),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH14_EN = (0x1 << 6),
> + MAX98927_PCM_Tx_Enables_B_PCM_TX_CH15_EN = (0x1 << 7),
> +
> + /* PCM Tx HiZ Control A (Address 0x001c)*/
> + MAX98927_PCM_Tx_HiZ_Control_A = 0x001c,
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH0_HIZ = (0x1 << 0),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH1_HIZ = (0x1 << 1),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH2_HIZ = (0x1 << 2),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH3_HIZ = (0x1 << 3),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH4_HIZ = (0x1 << 4),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH5_HIZ = (0x1 << 5),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH6_HIZ = (0x1 << 6),
> + MAX98927_PCM_Tx_HiZ_Control_A_PCM_TX_CH7_HIZ = (0x1 << 7),
> +
> + /* PCM Tx HiZ Control B (Address 0x001d)*/
> + MAX98927_PCM_Tx_HiZ_Control_B = 0x001d,
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH8_HIZ = (0x1 << 0),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH9_HIZ = (0x1 << 1),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH10_HIZ = (0x1 << 2),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH11_HIZ = (0x1 << 3),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH12_HIZ = (0x1 << 4),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH13_HIZ = (0x1 << 5),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH14_HIZ = (0x1 << 6),
> + MAX98927_PCM_Tx_HiZ_Control_B_PCM_TX_CH15_HIZ = (0x1 << 7),
> +
> + /* PCM Tx Channel Sources A (Address 0x001e)*/
> + MAX98927_PCM_Tx_Channel_Sources_A = 0x001e,
> + MAX98927_PCM_Tx_Channel_Sources_A_PCM_IVADC_V_DEST_Mask = (0xf << 0),
> + MAX98927_PCM_Tx_Channel_Sources_A_PCM_IVADC_I_DEST_Mask = (0xf << 4),
> +
> + /* PCM Tx Channel Sources B (Address 0x001f)*/
> + MAX98927_PCM_Tx_Channel_Sources_B = 0x001f,
> + MAX98927_PCM_Tx_Channel_Sources_B_PCM_AMP_DSP_DEST_Mask = (0xf << 0),
> + MAX98927_PCM_Tx_Channel_Src_INTERLEAVE_Mask = (0x1 << 5),
> +
> + /* PCM Mode Config (Address 0x0020)*/
> + MAX98927_PCM_Mode_Config = 0x0020,
> + MAX98927_PCM_Mode_Config_PCM_TX_EXTRA_HIZ = (0x1 << 0),
> + MAX98927_PCM_Mode_Config_PCM_CHANSEL = (0x1 << 1),
> + MAX98927_PCM_Mode_Config_PCM_BCLKEDGE = (0x1 << 2),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_Mask = (0x7 << 3),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_I2S = (0x0 << 3),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_LEFT = (0x1 << 3),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_0 = (0x3 << 3),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_1 = (0x4 << 3),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_TDM_2 = (0x5 << 3),
> + MAX98927_PCM_Mode_Config_PCM_FORMAT_ = (0x6 << 3),
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_Mask = (0x3 << 6),
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_16 = (0x1 << 6),
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_24 = (0x2 << 6),
> + MAX98927_PCM_Mode_Config_PCM_CHANSZ_32 = (0x3 << 6),
> +
> + /* PCM Master Mode (Address 0x0021)*/
> + MAX98927_PCM_Master_Mode = 0x0021,
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_Mask = (0x3 << 0),
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_SLAVE = (0x0 << 0),
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_MASTER = (0x3 << 0),
> + MAX98927_PCM_Master_Mode_PCM_MSTR_MODE_HYBRID = (0x1 << 0),
> + MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_Mask = (0xf << 2),
> + MAX98927_PCM_Master_Mode_PCM_CLK_SOURCE = (0x1 << 6),
> +
> + /* PCM Clock setup (Address 0x0022)*/
> + MAX98927_PCM_Clock_setup = 0x0022,
> + MAX98927_PCM_Clock_setup_PCM_BSEL_Mask = (0xf << 0),
> + MAX98927_PCM_Clock_setup_PCM_MSEL_Mask = (0xf << 4),
> +
> + /* PCM Sample rate setup 1 (Address 0x0023)*/
> + MAX98927_PCM_Sample_rate_setup_1 = 0x0023,
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_Mask = (0xf << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_8000 = (0x0 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_11025 = (0x1 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_12000 = (0x2 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_16000 = (0x3 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_22050 = (0x4 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_24000 = (0x5 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_32000 = (0x6 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_44100 = (0x7 << 0),
> + MAX98927_PCM_Sample_rate_setup_1_DIG_IF_SR_48000 = (0x8 << 0),
> +
> + /* PCM Sample rate setup 1 (Address 0x0024)*/
> + MAX98927_PCM_Sample_rate_setup_2 = 0x0024,
> + MAX98927_PCM_Sample_rate_setup_2_IVADC_SR_Mask = (0xf << 0),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_Mask = (0xf << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0001 = (0x0 << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0011 = (0x2 << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0101 = (0x4 << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_0111 = (0x6 << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1001 = (0x8 << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1011 = (0xa << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_1101 = (0xc << 4),
> + MAX98927_PCM_Sample_rate_setup_2_SPK_SR_ = (0xf << 4),
> +
> + /* PCM to speaker monomix A (Address 0x0025)*/
> + MAX98927_PCM_to_speaker_monomix_A = 0x0025,
> + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CH0_SOURCE_Mask = (0xf << 0),
> + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_Mask = (0x3 << 6),
> + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_1 = (0x0 << 6),
> + MAX98927_PCM_to_spkmonomix_A_DMONOMIX_CFG_3 = (0x0 << 6),
> +
> + /* PCM to speaker monomix B (Address 0x0026)*/
> + MAX98927_PCM_to_spkmonomix_B = 0x0026,
> + MAX98927_PCM_to_spkmonomix_B_DMONOMIX_CH1_SOURCE_Mask = (0xf << 0),
> +
> + /* ICC RX Enables A (Address 0x0027)*/
> + MAX98927_ICC_RX_Enables_A = 0x0027,
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH0_EN = (0x1 << 0),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH1_EN = (0x1 << 1),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH2_EN = (0x1 << 2),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH3_EN = (0x1 << 3),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH4_EN = (0x1 << 4),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH5_EN = (0x1 << 5),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH6_EN = (0x1 << 6),
> + MAX98927_ICC_RX_Enables_A_ICC_RX_CH7_EN = (0x1 << 7),
> +
> + /* ICC RX Enables B (Address 0x0028)*/
> + MAX98927_ICC_RX_Enables_B = 0x0028,
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH8_EN = (0x1 << 0),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH9_EN = (0x1 << 1),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH10_EN = (0x1 << 2),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH11_EN = (0x1 << 3),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH12_EN = (0x1 << 4),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH13_EN = (0x1 << 5),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH14_EN = (0x1 << 6),
> + MAX98927_ICC_RX_Enables_B_ICC_RX_CH15_EN = (0x1 << 7),
> +
> + /* ICC TX Enables A (Address 0x002b)*/
> + MAX98927_ICC_TX_Enables_A = 0x002b,
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH0_EN = (0x1 << 0),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH1_EN = (0x1 << 1),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH2_EN = (0x1 << 2),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH3_EN = (0x1 << 3),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH4_EN = (0x1 << 4),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH5_EN = (0x1 << 5),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH6_EN = (0x1 << 6),
> + MAX98927_ICC_TX_Enables_A_ICC_TX_CH7_EN = (0x1 << 7),
> +
> + /* ICC TX Enables B (Address 0x002c)*/
> + MAX98927_ICC_TX_Enables_B = 0x002c,
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH8_EN = (0x1 << 0),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH9_EN = (0x1 << 1),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH10_EN = (0x1 << 2),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH11_EN = (0x1 << 3),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH12_EN = (0x1 << 4),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH13_EN = (0x1 << 5),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH14_EN = (0x1 << 6),
> + MAX98927_ICC_TX_Enables_B_ICC_TX_CH15_EN = (0x1 << 7),
> +
> + /* ICC Data Order Select (Address 0x002d)*/
> + MAX98927_ICC_Data_Order_Select = 0x002d,
> + MAX98927_ICC_Data_Order_Select_ICC_DRIVE_MODE = (0x1 << 3),
> +
> + /* ICC HiZ Manual Mode (Address 0x002e)*/
> + MAX98927_ICC_HiZ_Manual_Mode = 0x002e,
> + MAX98927_ICC_HiZ_Manual_Mode_ICC_TX_HIZ_MANUAL = (0x1 << 0),
> + MAX98927_ICC_HiZ_Manual_Mode_ICC_TX_EXTRA_HIZ = (0x1 << 1),
> +
> + /* ICC TX HiZ Enables A (Address 0x002f)*/
> + MAX98927_ICC_TX_HiZ_Enables_A = 0x002f,
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH0_HIZ = (0x1 << 0),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH1_HIZ = (0x1 << 1),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH2_HIZ = (0x1 << 2),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH3_HIZ = (0x1 << 3),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH4_HIZ = (0x1 << 4),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH5_HIZ = (0x1 << 5),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH6_HIZ = (0x1 << 6),
> + MAX98927_ICC_TX_HiZ_Enables_A_ICC_TX_CH7_HIZ = (0x1 << 7),
> +
> + /* ICC TX HiZ Enables B (Address 0x0030)*/
> + MAX98927_ICC_TX_HiZ_Enables_B = 0x0030,
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH8_HIZ = (0x1 << 0),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH9_HIZ = (0x1 << 1),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH10_HIZ = (0x1 << 2),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH11_HIZ = (0x1 << 3),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH12_HIZ = (0x1 << 4),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH13_HIZ = (0x1 << 5),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH14_HIZ = (0x1 << 6),
> + MAX98927_ICC_TX_HiZ_Enables_B_ICC_TX_CH15_HIZ = (0x1 << 7),
> +
> + /* ICC Link Enables (Address 0x0031)*/
> + MAX98927_ICC_Link_Enables = 0x0031,
> + MAX98927_ICC_Link_Enables_ICC_LINK_EN = (0x1 << 1),
> +
> + /* PDM Tx Enables (Address 0x0032)*/
> + MAX98927_PDM_Tx_Enables = 0x0032,
> + MAX98927_PDM_Tx_Enables_PDM_TX_EN = (0x1 << 0),
> + MAX98927_PDM_Tx_Enables_PDM_TX_CLK_DIV2 = (0x1 << 1),
> +
> + /* PDM Tx HiZ Control (Address 0x0033)*/
> + MAX98927_PDM_Tx_HiZ_Control = 0x0033,
> + MAX98927_PDM_Tx_HiZ_Control_PDM_TX_HIZ = (0x1 << 0),
> +
> + /* PDM Tx Control (Address 0x0034)*/
> + MAX98927_PDM_Tx_Control = 0x0034,
> + MAX98927_PDM_Tx_Control_PDM_TX_CH0_SOURCE = (0x1 << 0),
> + MAX98927_PDM_Tx_Control_PDM_TX_CH1_SOURCE = (0x1 << 1),
> +
> + /* PDM Rx Enable (Address 0x0034)*/
> + MAX98927_PDM_Rx_Enable = 0x0035,
> + MAX98927_PDM_Rx_Enable_PDM_RX_EN = (0x1 << 0),
> + MAX98927_PDM_Rx_Enable_PDM_DSP_EN = (0x1 << 1),
> + MAX98927_PDM_Rx_Enable_PDM_DITH_EN = (0x1 << 2),
> + MAX98927_PDM_Rx_Enable_PDM_RX_CH_SEL = (0x1 << 3),
> + MAX98927_PDM_Rx_Enable_PDM_FIFO_RDY_LVL_Mask = (0xf << 4),
> +
> + /* AMP volume control (Address 0x0036)*/
> + MAX98927_AMP_volume_control = 0x0036,
> + MAX98927_AMP_volume_control_AMP_VOL_Mask = (0x7f << 0),
> + MAX98927_AMP_volume_control_AMP_VOL_SEL = (0x1 << 7),
> +
> + /* AMP DSP Config (Address 0x0037)*/
> + MAX98927_AMP_DSP_Config = 0x0037,
> + MAX98927_AMP_DSP_Config_AMP_DCBLK_EN = (0x1 << 0),
> + MAX98927_AMP_DSP_Config_AMP_DITH_EN = (0x1 << 1),
> + MAX98927_AMP_DSP_Config_DAC_HALF_REF_CURRENT = (0x1 << 2),
> + MAX98927_AMP_DSP_Config_DAC_DOUBLE_RFB = (0x1 << 3),
> + MAX98927_AMP_DSP_Config_AMP_VOL_RMP_BYPASS = (0x1 << 4),
> + MAX98927_AMP_DSP_Config_DAC_INVERT = (0x1 << 5),
> +
> + /* Tone Generator and DC Config (Address 0x0038)*/
> + MAX98927_Tone_Generator_and_DC_Config = 0x0038,
> + MAX98927_Tone_Generator_and_DC_Config_TONE_CONFIG_Mask = (0xf << 0),
> +
> + /* DRE Control (Address 0x0039)*/
> + MAX98927_DRE_Control = 0x0039,
> + MAX98927_DRE_Control_DRE_EN = (0x1 << 0),
> +
> + /* AMP enables (Address 0x003a)*/
> + MAX98927_AMP_enables = 0x003a,
> + MAX98927_AMP_enables_SPK_EN = (0x1 << 0),
> +
> + /* Speaker source select (Address 0x003b)*/
> + MAX98927_Speaker_source_select = 0x003b,
> + MAX98927_Speaker_source_select_SPK_SOURCE_Mask = (0x3 << 0),
> + MAX98927_Speaker_source_select_SPK_SOURCE_01 = (0x0 << 0),
> + MAX98927_Speaker_source_select_SPK_SOURCE_11 = (0x2 << 0),
> +
> + /* Speaker Gain (Address 0x003c)*/
> + MAX98927_Speaker_Gain = 0x003c,
> + MAX98927_Speaker_Gain_SPK_PCM_GAIN_Mask = (0x7 << 0),
> + MAX98927_Speaker_Gain_SPK_PCM_GAIN_001 = (0x0 << 0),
> + MAX98927_Speaker_Gain_SPK_PCM_GAIN_011 = (0x2 << 0),
> + MAX98927_Speaker_Gain_SPK_PCM_GAIN_101 = (0x4 << 0),
> + MAX98927_Speaker_Gain_SPK_PCM_GAIN_111 = (0x6 << 0),
> + MAX98927_Speaker_Gain_SPK_PDM_GAIN_Mask = (0x7 << 4),
> + MAX98927_Speaker_Gain_SPK_PDM_GAIN_001 = (0x0 << 4),
> + MAX98927_Speaker_Gain_SPK_PDM_GAIN_011 = (0x2 << 4),
> + MAX98927_Speaker_Gain_SPK_PDM_GAIN_101 = (0x4 << 4),
> + MAX98927_Speaker_Gain_SPK_PDM_GAIN_111 = (0x6 << 4),
> +
> + /* SSM Configuration (Address 0x003d)*/
> + MAX98927_SSM_Configuration = 0x003d,
> + MAX98927_SSM_Configuration_SSM_MOD_INDEX_Mask = (0x7 << 0),
> + MAX98927_SSM_Configuration_SSM_MOD_INDEX_001 = (0x0 << 0),
> + MAX98927_SSM_Configuration_SSM_MOD_INDEX_011 = (0x2 << 0),
> + MAX98927_SSM_Configuration_SSM_MOD_INDEX_101 = (0x4 << 0),
> + MAX98927_SSM_Configuration_SSM_MOD_INDEX_ = (0x6 << 0),
> + MAX98927_SSM_Configuration_SPK_FSW_SEL = (0x1 << 3),
> + MAX98927_SSM_Configuration_SSM_ENA = (0x1 << 7),
> +
> + /* Measurement enables (Address 0x003e)*/
> + MAX98927_Measurement_enables = 0x003e,
> + MAX98927_Measurement_enables_IVADC_V_EN = (0x1 << 0),
> + MAX98927_Measurement_enables_IVADC_I_EN = (0x1 << 1),
> +
> + /* Measurement DSP Config (Address 0x003f)*/
> + MAX98927_Measurement_DSP_Config = 0x003f,
> + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_EN = (0x1 << 0),
> + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_EN = (0x1 << 1),
> + MAX98927_Measurement_DSP_Config_MEAS_DITH_EN = (0x1 << 2),
> + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_Mask = (0x3 << 4),
> + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_01 = (0x0 << 4),
> + MAX98927_Measurement_DSP_Config_MEAS_V_DCBLK_11 = (0x2 << 4),
> + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_Mask = (0x3 << 6),
> + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_01 = (0x0 << 6),
> + MAX98927_Measurement_DSP_Config_MEAS_I_DCBLK_11 = (0x2 << 6),
> +
> + /* Boost Control 0 (Address 0x0040)*/
> + MAX98927_Boost_Control_0 = 0x0040,
> + MAX98927_Boost_Control_0_BST_VOUT_Mask = (0x1f << 0),
> + MAX98927_Boost_Control_0_EXT_PVDD_EN = (0x1 << 7),
> +
> + /* Boost Control 3 (Address 0x0041)*/
> + MAX98927_Boost_Control_3 = 0x0041,
> + MAX98927_Boost_Control_3_BST_SKIPLOAD_Mask = (0x3 << 0),
> + MAX98927_Boost_Control_3_BST_SKIPLOAD_01 = (0x0 << 0),
> + MAX98927_Boost_Control_3_BST_SKIPLOAD_11 = (0x2 << 0),
> + MAX98927_Boost_Control_3_BST_PHASE_Mask = (0x7 << 2),
> + MAX98927_Boost_Control_3_BST_PHASE_001 = (0x0 << 2),
> + MAX98927_Boost_Control_3_BST_PHASE_011 = (0x2 << 2),
> + MAX98927_Boost_Control_3_BST_PHASE_ = (0x1 << 2),
> + MAX98927_Boost_Control_3_BST_SLOWSTART = (0x1 << 5),
> +
> + /* Boost Control 1 (Address 0x0042)*/
> + MAX98927_Boost_Control_1 = 0x0042,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Boost_Control_1_BST_ILIM_Mask = (0x3f << 0),
> +
> + /* Meas ADC Config (Address 0x0043)*/
> + MAX98927_Meas_ADC_Config = 0x0043,
> + MAX98927_Meas_ADC_Config_MEAS_ADC_CH0_EN = (0x1 << 0),
> + MAX98927_Meas_ADC_Config_MEAS_ADC_CH1_EN = (0x1 << 1),
> + MAX98927_Meas_ADC_Config_MEAS_ADC_CH2_EN = (0x1 << 2),
> +
> + /* Meas ADC Base Divide MSByte (Address 0x0044)*/
> + MAX98927_Meas_ADC_Base_Divide_MSByte = 0x0044,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Base_Divide_MSByte_MEAS_ADC_BASE_DIV_Mask
> + = (0xff << 0),
> +
> + /* Meas ADC Base Divide LSByte (Address 0x0045)*/
> + MAX98927_Meas_ADC_Base_Divide_LSByte = 0x0045,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Base_Divide_LSByte_MEAS_ADC_BASE_DIV_Mask
> + = (0xff << 0),
> +
> + /* Meas ADC Chan 0 Divide (Address 0x0046)*/
> + MAX98927_Meas_ADC_Chan_0_Divide = 0x0046,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Chan_0_Divide_MEAS_ADC_CH0_DIV_Mask = (0xff << 0),
> +
> + /* Meas ADC Chan 1 Divide (Address 0x0047)*/
> + MAX98927_Meas_ADC_Chan_1_Divide = 0x0047,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Chan_1_Divide_MEAS_ADC_CH1_DIV_Mask = (0xff << 0),
> +
> + /* Meas ADC Chan 2 Divide (Address 0x0048)*/
> + MAX98927_Meas_ADC_Chan_2_Divide = 0x0048,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Chan_2_Divide_MEAS_ADC_CH2_DIV_Mask = (0xff << 0),
> +
> + /* Meas ADC Chan 0 Filt Config (Address 0x0049)*/
> + MAX98927_Meas_ADC_Chan_0_Filt_Config = 0x0049,
> + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_Mask
> + = (0x7 << 0),
> + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_001
> + = (0x0 << 0),
> + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_011
> + = (0x2 << 0),
> + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_AVG_101
> + = (0x4 << 0),
> + MAX98927_Meas_ADC_Chan_0_Filt_Config_MEAS_ADC_CH0_FILT_EN
> + = (0x1 << 3),
> +
> + /* Meas ADC Chan 1 Filt Config (Address 0x004a)*/
> + MAX98927_Meas_ADC_Chan_1_Filt_Config = 0x004a,
> + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_Mask
> + = (0x7 << 0),
> + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_001
> + = (0x0 << 0),
> + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_011
> + = (0x2 << 0),
> + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_AVG_101
> + = (0x4 << 0),
> + MAX98927_Meas_ADC_Chan_1_Filt_Config_MEAS_ADC_CH1_FILT_EN
> + = (0x1 << 3),
> +
> + /* Meas ADC Chan 2 Filt Config (Address 0x004b)*/
> + MAX98927_Meas_ADC_Chan_2_Filt_Config = 0x004b,
> + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_Mask
> + = (0x7 << 0),
> + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_001
> + = (0x0 << 0),
> + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_011
> + = (0x2 << 0),
> + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_AVG_101
> + = (0x4 << 0),
> + MAX98927_Meas_ADC_Chan_2_Filt_Config_MEAS_ADC_CH2_FILT_EN
> + = (0x1 << 3),
> +
> + /* Meas ADC Chan 0 Readback (Address 0x004c)*/
> + MAX98927_Meas_ADC_Chan_0_Readback = 0x004c,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Chan_0_Readback_MEAS_ADC_CH0_DATA_Mask
> + = (0xff << 0),
> +
> + /* Meas ADC Chan 1 Readback (Address 0x004d)*/
> + MAX98927_Meas_ADC_Chan_1_Readback = 0x004d,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Chan_1_Readback_MEAS_ADC_CH1_DATA_Mask
> + = (0xff << 0),
> +
> + /* Meas ADC Chan 2 Readback (Address 0x004e)*/
> + MAX98927_Meas_ADC_Chan_2_Readback = 0x004e,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Meas_ADC_Chan_2_Readback_MEAS_ADC_CH2_DATA_Mask
> + = (0xff << 0),
> +
> + /* Brownout status (Address 0x0051)*/
> + MAX98927_Brownout_status = 0x0051,
> + MAX98927_Brownout_status_BDE_STATE_Mask = (0xf << 0),
> +
> + /* Brownout enables (Address 0x0052)*/
> + MAX98927_Brownout_enables = 0x0052,
> + MAX98927_Brownout_enables_BDE_EN = (0x1 << 0),
> + MAX98927_Brownout_enables_BDE_AMP_EN = (0x1 << 1),
> + MAX98927_Brownout_enables_AMP_DSP_EN = (0x1 << 2),
> +
> + /* Brownout level infinite hold (Address 0x0053)*/
> + MAX98927_Brownout_level_infinite_hold = 0x0053,
> + MAX98927_Brownout_level_infinite_hold_BDE_L8_INF_HLD = (0x1 << 1),
> +
> + /* Brownout level infinite hold clear (Address 0x0054)*/
> + MAX98927_Brownout_level_infinite_hold_clear = 0x0054,
> + MAX98927_Brownout_level_infinite_hold_clear_BDE_L8_HLD_RLS
> + = (0x1 << 1),
> +
> + /* Brownout level hold (Address 0x0055)*/
> + MAX98927_Brownout_level_hold = 0x0055,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout_level_hold_BDE_HLD_Mask = (0xff << 0),
> +
> + /* Brownout level 1 threshold (Address 0x0056)*/
> + MAX98927_Brownout__level_1_threshold = 0x0056,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_1_threshold_BDE_L1_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 2 threshold (Address 0x0057)*/
> + MAX98927_Brownout__level_2_threshold = 0x0057,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_2_threshold_BDE_L2_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 3 threshold (Address 0x0058)*/
> + MAX98927_Brownout__level_3_threshold = 0x0058,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_3_threshold_BDE_L3_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 4 threshold (Address 0x0059)*/
> + MAX98927_Brownout__level_4_threshold = 0x0059,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_4_threshold_BDE_L4_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 5 threshold (Address 0x005a)*/
> + MAX98927_Brownout__level_5_threshold = 0x005a,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_5_threshold_BDE_L5_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 6 threshold (Address 0x005b)*/
> + MAX98927_Brownout__level_6_threshold = 0x005b,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_6_threshold_BDE_L6_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 7 threshold (Address 0x005c)*/
> + MAX98927_Brownout__level_7_threshold = 0x005c,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_7_threshold_BDE_L7_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout level 8 threshold (Address 0x005d)*/
> + MAX98927_Brownout__level_8_threshold = 0x005d,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_8_threshold_BDE_L8_VTHRESH_Mask = (0xff << 0),
> +
> + /* Brownout threshold hysterysis (Address 0x005e)*/
> + MAX98927_Brownout_threshold_hysterysis = 0x005e,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout_threshold_hysterysis_BDE_VTHRESH_HYST_Mask
> + = (0xff << 0),
> + /* Brownout AMP limiter attack/release (Address 0x005f)*/
> + MAX98927_Brownout_AMP_limiter_attack_release = 0x005f,
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_Mask
> + = (0xf << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0001
> + = (0x0 << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0011
> + = (0x2 << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0101
> + = (0x4 << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_0111
> + = (0x6 << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1001
> + = (0x8 << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1011
> + = (0xa << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1101
> + = (0xc << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_RLS_1111
> + = (0xe << 0),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_Mask
> + = (0xf << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0001
> + = (0x0 << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0011
> + = (0x2 << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0101
> + = (0x4 << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_0111
> + = (0x6 << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1001
> + = (0x8 << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1011
> + = (0xa << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1101
> + = (0xc << 4),
> + MAX98927_Brownout_AMP_limiter_attack_release_AMP_LIM_ATK_1111
> + = (0xe << 4),
> +
> + /* Brownout AMP gain attack/release (Address 0x0060)*/
> + MAX98927_Brownout_AMP_gain_attack_release = 0x0060,
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_Mask
> + = (0xf << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0001
> + = (0x0 << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0011
> + = (0x2 << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0101
> + = (0x4 << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_0111
> + = (0x6 << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1001
> + = (0x8 << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1011
> + = (0xa << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1101
> + = (0xc << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_RLS_1111
> + = (0xe << 0),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_Mask
> + = (0xf << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0001
> + = (0x0 << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0011
> + = (0x2 << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0101
> + = (0x4 << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_0111
> + = (0x6 << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1001
> + = (0x8 << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1011
> + = (0xa << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1101
> + = (0xc << 4),
> + MAX98927_Brownout_AMP_gain_attack_release_AMP_GAIN_ATK_1111
> + = (0xe << 4),
> +
> + /* Brownout AMP1 clip mode (Address 0x0061)*/
> + MAX98927_Brownout_AMP1_clip_mode = 0x0061,
> + MAX98927_Brownout_AMP1_clip_mode_AMP_CLIP_MODE = (0x1 << 0),
> +
> + /* Brownout level 1 current limit (Address 0x0062)*/
> + MAX98927_Brownout__level_1_current_limit = 0x0062,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_1_current_limit_BDE_L1_ILIM_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 1 amp 1 control 1 (Address 0x0063)*/
> + MAX98927_Brownout__level_1_amp_1_control_1 = 0x0063,
> + MAX98927_Brownout__level_1_amp_1_control_1_BDE_L1_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 1 amp 1 control 2 (Address 0x0064)*/
> + MAX98927_Brownout__level_1_amp_1_control_2 = 0x0064,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_1_amp_1_control_2_BDE_L1_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 1 amp 1 control 3 (Address 0x0065)*/
> + MAX98927_Brownout__level_1_amp_1_control_3 = 0x0065,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_1_amp_1_control_3_BDE_L1_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 2 current limit (Address 0x0066)*/
> + MAX98927_Brownout__level_2_current_limit = 0x0066,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_2_current_limit_BDE_L2_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 2 amp 1 control 1 (Address 0x0067)*/
> + MAX98927_Brownout__level_2_amp_1_control_1 = 0x0067,
> + MAX98927_Brownout__level_2_amp_1_control_1_BDE_L2_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 2 amp 1 control 2 (Address 0x0068)*/
> + MAX98927_Brownout__level_2_amp_1_control_2 = 0x0068,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_2_amp_1_control_2_BDE_L2_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 2 amp 1 control 3 (Address 0x0069)*/
> + MAX98927_Brownout__level_2_amp_1_control_3 = 0x0069,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_2_amp_1_control_3_BDE_L2_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 3 current limit (Address 0x006a)*/
> + MAX98927_Brownout__level_3_current_limit = 0x006a,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_3_current_limit_BDE_L3_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 3 amp 1 control 1 (Address 0x006b)*/
> + MAX98927_Brownout__level_3_amp_1_control_1 = 0x006b,
> + MAX98927_Brownout__level_3_amp_1_control_1_BDE_L3_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 3 amp 1 control 2 (Address 0x006c)*/
> + MAX98927_Brownout__level_3_amp_1_control_2 = 0x006c,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_3_amp_1_control_2_BDE_L3_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 3 amp 1 control 3 (Address 0x006d)*/
> + MAX98927_Brownout__level_3_amp_1_control_3 = 0x006d,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_3_amp_1_control_3_BDE_L3_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 4 current limit (Address 0x006e)*/
> + MAX98927_Brownout__level_4_current_limit = 0x006e,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_4_current_limit_BDE_L4_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 4 amp 1 control 1 (Address 0x006f)*/
> + MAX98927_Brownout__level_4_amp_1_control_1 = 0x006f,
> + MAX98927_Brownout__level_4_amp_1_control_1_BDE_L4_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 4 amp 1 control 2 (Address 0x0070)*/
> + MAX98927_Brownout__level_4_amp_1_control_2 = 0x0070,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_4_amp_1_control_2_BDE_L4_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 4 amp 1 control 3 (Address 0x0071)*/
> + MAX98927_Brownout__level_4_amp_1_control_3 = 0x0071,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_4_amp_1_control_3_BDE_L4_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 5 current limit (Address 0x0072)*/
> + MAX98927_Brownout__level_5_current_limit = 0x0072,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_5_current_limit_BDE_L5_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 5 amp 1 control 1 (Address 0x0073)*/
> + MAX98927_Brownout__level_5_amp_1_control_1 = 0x0073,
> + MAX98927_Brownout__level_5_amp_1_control_1_BDE_L5_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 5 amp 1 control 2 (Address 0x0074)*/
> + MAX98927_Brownout__level_5_amp_1_control_2 = 0x0074,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_5_amp_1_control_2_BDE_L5_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 5 amp 1 control 3 (Address 0x0075)*/
> + MAX98927_Brownout__level_5_amp_1_control_3 = 0x0075,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_5_amp_1_control_3_BDE_L5_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 6 current limit (Address 0x0076)*/
> + MAX98927_Brownout__level_6_current_limit = 0x0076,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_6_current_limit_BDE_L6_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 6 amp 1 control 1 (Address 0x0077)*/
> + MAX98927_Brownout__level_6_amp_1_control_1 = 0x0077,
> + MAX98927_Brownout__level_6_amp_1_control_1_BDE_L6_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 6 amp 1 control 2 (Address 0x0078)*/
> + MAX98927_Brownout__level_6_amp_1_control_2 = 0x0078,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_6_amp_1_control_2_BDE_L6_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 6 amp 1 control 3 (Address 0x0079)*/
> + MAX98927_Brownout__level_6_amp_1_control_3 = 0x0079,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_6_amp_1_control_3_BDE_L6_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 7 current limit (Address 0x007a)*/
> + MAX98927_Brownout__level_7_current_limit = 0x007a,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_7_current_limit_BDE_L7_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 7 amp 1 control 1 (Address 0x007b)*/
> + MAX98927_Brownout__level_7_amp_1_control_1 = 0x007b,
> + MAX98927_Brownout__level_7_amp_1_control_1_BDE_L7_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 7 amp 1 control 2 (Address 0x007c)*/
> + MAX98927_Brownout__level_7_amp_1_control_2 = 0x007c,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_7_amp_1_control_2_BDE_L7_AMP1_CLIP_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 7 amp 1 control 3 (Address 0x007d)*/
> + MAX98927_Brownout__level_7_amp_1_control_3 = 0x007d,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_7_amp_1_control_3_BDE_L7_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Brownout level 8 current limit (Address 0x007e)*/
> + MAX98927_Brownout__level_8_current_limit = 0x007e,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_8_current_limit_BDE_L8_ILIM_Mask = (0x3f << 0),
> +
> + /* Brownout level 8 amp 1 control 1 (Address 0x007f)*/
> + MAX98927_Brownout__level_8_amp_1_control_1 = 0x007f,
> + MAX98927_Brownout__level_8_amp_1_control_1_BDE_L8_AMP1_LIM_Mask
> + = (0xf << 0),
> +
> + /* Brownout level 8 amp 1 control 2 (Address 0x0080)*/
> + MAX98927_Brownout__lvl_8_amp_1_control_2 = 0x0080,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__lvl_8_amp_1_control_2_BDE_L8_AMP1_CLIP_Mask
> + = (0x3f << 0),
> + MAX98927_Brownout__lvl_8_amp_1_control_2_BDE_L8_AMP1_MUTE
> + = (0x1 << 7),
> +
> + /* Brownout level 8 amp 1 control 3 (Address 0x0081)*/
> + MAX98927_Brownout__level_8_amp_1_control_3 = 0x0081,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Brownout__level_8_amp_1_control_3_BDE_L8_AMP1_GAIN_Mask
> + = (0x3f << 0),
> +
> + /* Env Tracker Vout Headroom (Address 0x0082)*/
> + MAX98927_Env_Tracker_Vout_Headroom = 0x0082,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Env_Tracker_Vout_Head_ENV_TRACKER_BST_VOUT_HEADROOM_Mask
> + = (0x1f << 0),
> +
> + /* Env Tracker Boost Vout Delay (Address 0x0083)*/
> + MAX98927_Env_Tracker_Boost_Vout_Delay = 0x0083,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Env_Tracker_Boost_V_Delay_ENV_TRACKER_BST_VOUT_DELAY_Mask
> + = (0x1f << 0),
> + MAX98927_Env_Tracker_Boost_Vout_Delay_ENV_TRACKER_BDE_MODE
> + = (0x1 << 7),
> +
> + /* Env Tracker Release Rate (Address 0x0084)*/
> + MAX98927_Env_Tracker_Release_Rate = 0x0084,
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_Mask
> + = (0x7 << 0),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_001
> + = (0x0 << 0),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_011
> + = (0x2 << 0),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_101
> + = (0x4 << 0),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_111
> + = (0x6 << 0),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_PEAK_DET_LPF_BYP_EN
> + = (0x1 << 3),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_Mask
> + = (0x3 << 4),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_01
> + = (0x0 << 4),
> + MAX98927_Env_Tracker_Release_Rate_ENV_TRACKER_RLS_RATE_SCALE_11
> + = (0x2 << 4),
> +
> + /* Env Tracker Hold Rate (Address 0x0085)*/
> + MAX98927_Env_Tracker_Hold_Rate = 0x0085,
> + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_Mask
> + = (0x7 << 0),
> + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_001
> + = (0x0 << 0),
> + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_011
> + = (0x2 << 0),
> + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_101
> + = (0x4 << 0),
> + MAX98927_Env_Tracker_Hold_Rate_ENV_TRACKER_HOLD_RATE_111
> + = (0x6 << 0),
> +
> + /* Env Tracker Control (Address 0x0086)*/
> + MAX98927_Env_Tracker_Control = 0x0086,
> + MAX98927_Env_Tracker_Control_ENV_TRACKER_EN = (0x1 << 0),
> +
> + /* Env Tracker Boost Vout ReadBack (Address 0x0087)*/
> + MAX98927_Env_Tracker__Boost_Vout_ReadBack = 0x0087,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Env_Tracker__Boost_Vout_RB_ENV_TRACKER_BST_VOUT_RD_Mask
> + = (0x1f << 0),
> +
> + /* Advanced Settings (Address 0x0089)*/
> + MAX98927_Advanced_Settings = 0x0089,
> + MAX98927_Advanced_Settings_DAC_HALF_FIR = (0x1 << 0),
> + MAX98927_Advanced_Settings_PDM_MOD_SEL = (0x1 << 1),
> + MAX98927_Advanced_Settings_ISOCH_EN = (0x1 << 2),
> +
> + /* DAC Test 1 (Address 0x009f)*/
> + MAX98927_DAC_Test_1 = 0x009f,
> + MAX98927_DAC_Test_1_DAC_PCM_TIMING = (0x1 << 0),
> + MAX98927_DAC_Test_1_DAC_HALFI_AMP = (0x1 << 1),
> + MAX98927_DAC_Test_1_DAC_LONG_HOLD = (0x1 << 3),
> + MAX98927_DAC_Test_1_DAC_DISABLE_CHOP = (0x1 << 4),
> + MAX98927_DAC_Test_1_DAC_TM = (0x1 << 5),
> + MAX98927_DAC_Test_1_DAC_INVERT_DACCLK = (0x1 << 6),
> +
> + /* Authentication key 0 (Address 0x00ea)*/
> + MAX98927_Authentication_key_0 = 0x00ea,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_key_0_AUTH_KEY_Mask = (0xff << 0),
> +
> + /* Authentication key 1 (Address 0x00eb)*/
> + MAX98927_Authentication_key_1 = 0x00eb,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_key_1_AUTH_KEY_Mask = (0xff << 0),
> +
> + /* Authentication key 2 (Address 0x00ec)*/
> + MAX98927_Authentication_key_2 = 0x00ec,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_key_2_AUTH_KEY_Mask = (0xff << 0),
> +
> + /* Authentication key 3 (Address 0x00ed)*/
> + MAX98927_Authentication_key_3 = 0x00ed,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_key_3_AUTH_KEY_Mask = (0xff << 0),
> +
> + /* Authentication enable (Address 0x00ee)*/
> + MAX98927_Authentication_enable = 0x00ee,
> + MAX98927_Authentication_enable_AUTH_EN = (0x1 << 0),
> +
> + /* Authentication result 0 (Address 0x00ef)*/
> + MAX98927_Authentication_result_0 = 0x00ef,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_0_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 1 (Address 0x00f0)*/
> + MAX98927_Authentication_result_1 = 0x00f0,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_1_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 2 (Address 0x00f1)*/
> + MAX98927_Authentication_result_2 = 0x00f1,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_2_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 3 (Address 0x00f2)*/
> + MAX98927_Authentication_result_3 = 0x00f2,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_3_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 4 (Address 0x00f3)*/
> + MAX98927_Authentication_result_4 = 0x00f3,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_4_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 5 (Address 0x00f4)*/
> + MAX98927_Authentication_result_5 = 0x00f4,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_5_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 6 (Address 0x00f5)*/
> + MAX98927_Authentication_result_6 = 0x00f5,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_6_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 7 (Address 0x00f6)*/
> + MAX98927_Authentication_result_7 = 0x00f6,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_7_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 8 (Address 0x00f7)*/
> + MAX98927_Authentication_result_8 = 0x00f7,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_8_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 9 (Address 0x00f8)*/
> + MAX98927_Authentication_result_9 = 0x00f8,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_9_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 10 (Address 0x00f9)*/
> + MAX98927_Authentication_result_10 = 0x00f9,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_10_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 11 (Address 0x00fa)*/
> + MAX98927_Authentication_result_11 = 0x00fa,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_11_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 12 (Address 0x00fb)*/
> + MAX98927_Authentication_result_12 = 0x00fb,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_12_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 13 (Address 0x00fc)*/
> + MAX98927_Authentication_result_13 = 0x00fc,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_13_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 14 (Address 0x00fd)*/
> + MAX98927_Authentication_result_14 = 0x00fd,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_14_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Authentication result 15 (Address 0x00fe)*/
> + MAX98927_Authentication_result_15 = 0x00fe,
> + /*#BYHAND width >= 5:*/
> + MAX98927_Authentication_result_15_AUTH_RESULT_Mask = (0xff << 0),
> +
> + /* Global Enable (Address 0x00ff)*/
> + MAX98927_Global_Enable = 0x00ff,
> + MAX98927_Global_Enable_EN = (0x1 << 0),
> + /* Software Reset (Address 0x0100)*/
> + MAX98927_Software_Reset = 0x0100,
> + MAX98927_Software_Reset_RST = (0x1 << 0),
> +
> + /* REV ID (Address 0x01ff)*/
> + MAX98927_REV_ID = 0x01ff,
> + /*#BYHAND width >= 5:*/
> + MAX98927_REV_ID_REV_ID_Mask = (0xff << 0),
> +} MAX98927Registers;
> +
> +struct max98927_reg_default {
> + unsigned int ch;
> + unsigned int reg;
> + unsigned int def;
> +};
> +struct max98927_priv {
> + struct regmap *regmap;
> + struct regmap *sub_regmap;
> + struct snd_soc_codec *codec;
> + struct max98927_pdata *pdata;
> + const uint32_t *regcfg;
> + uint32_t regcfg_sz;
> + unsigned int spk_gain;
> + unsigned int sysclk;
> + unsigned int v_l_slot;
> + unsigned int i_l_slot;
> + unsigned int v_r_slot;
> + unsigned int i_r_slot;
> + bool interleave_mode;
> + unsigned int ch_size;
> + unsigned int rate;
> + unsigned int iface;
> + unsigned int master;
> + unsigned int thres_hyste;
> + unsigned int level5_hold;
> + unsigned int level6_hold;
> + unsigned int level7_hold;
> + unsigned int level8_hold;
> + unsigned int amp_limit;
> + unsigned int amp_limit_rel;
> + unsigned int amp1_level;
> + unsigned int amp2_level;
> + unsigned int amp3_level;
> + unsigned int amp1_level8;
> + unsigned int amp2_level8;
> + unsigned int amp3_level8;
> + unsigned int amp1_level7;
> + unsigned int amp2_level7;
> + unsigned int amp3_level7;
> + unsigned int amp1_level6;
> + unsigned int amp2_level6;
> + unsigned int amp3_level6;
> + unsigned int amp1_level5;
> + unsigned int amp2_level5;
> + unsigned int amp3_level5;
> + unsigned int digital_gain;
> + unsigned int pdm_gain;
> + unsigned int level_hold;
> + struct i2c_client *sub_i2c;
> + int sub_reg;
> + int sub_bus;
> +};
> +
> +#define MAX98927_GLOBAL_SHIFT 0
> +#define M98927_DAI_MSEL_SHIFT 4
> +#define M98927_DAI_BSEL_SHIFT 0
> +#define M98927_DAI_BSEL_32 (2 << M98927_DAI_BSEL_SHIFT)
> +#define M98927_DAI_BSEL_48 (3 << M98927_DAI_BSEL_SHIFT)
> +#define M98927_DAI_BSEL_64 (4 << M98927_DAI_BSEL_SHIFT)
> +#define M98927_DAI_MSEL_32 (2 << M98927_DAI_MSEL_SHIFT)
> +#define M98927_DAI_MSEL_48 (3 << M98927_DAI_MSEL_SHIFT)
> +#define M98927_DAI_MSEL_64 (4 << M98927_DAI_MSEL_SHIFT)
> +#define MAX98927_Speaker_Gain_Width 3
> +#define MAX98927_SPK_RMP_EN_SHIFT 4
> +#define MAX98927_PDM_GAIN_SHIFT 4
> +#define MAX98927_pdm_Gain_Width 3
> +#define MAX98927_AMP_VOL_WIDTH 7
> +#define MAX98927_AMP_VOL_LOCATION_SHIFT 7
> +#define MAX98927_PDM_Rx_Enable_PDM_CH_SHIFT 3
> +#define MAX98927_PCM_to_speaker_monomix_A_SHIFT 6
> +#define MAX98927_PCM_Sample_rate_setup_2_DIG_IF_SR_48000 (0x8 << 4)
> +#define MAX98927_PCM_FORMAT_DSP_A (0x3 << 3)
> +#define MAX98927_DRE_Control_DRE_SHIFT 0x1
> +#define MAX98927_PCM_Master_Mode_PCM_MCLK_RATE_SHIFT (2)
> +#define MAX98927_Brownout_AMP_limiter_attack_release_shift 4
> +#define MAX98927_BDE_DSP_SHIFT 2
> +#define MAX98927_Speaker_Gain_SPK_PDM_GAIN_SHIFT (4)
> +#define MAX98927_BDE_AMP_SHIFT (1)
> +#define MAX98927_PCM_Tx_Ch_Sources_A_I_SHIFT (4)
> +#endif
> --
> 1.9.1
>
--
| Michael Nazzareno Trimarchi Amarula Solutions BV |
| COO - Founder Cruquiuskade 47 |
| +31(0)851119172 Amsterdam 1018 AM NL |
| [`as] http://www.amarulasolutions.com |
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [alsa-devel] [PATCH v2] clkdev: add devm_of_clk_get()
From: Stephen Boyd @ 2016-11-23 19:10 UTC (permalink / raw)
To: Kuninori Morimoto
Cc: Michael Turquette, Rob Herring, Russell King, Mark Brown,
Linux-ALSA, Linux-DT, Linux-Kernel, linux-clk, Linux-ARM
In-Reply-To: <8737isvwc6.wl%kuninori.morimoto.gx@renesas.com>
On 11/16, Kuninori Morimoto wrote:
>
> Hi Rob, Michael, Russell
>
>
> What is the conclusion of this patch ?
> We shouldn't add devm_of_clk_get() ? or can I continue ?
>
> The problem of current [devm_]clk_get() handles *dev only,
> but I need to get clocks from DT node, not dev
>
> sound_soc {
> ...
> cpu {
> ...
> => clocks = <&xxx>;
> };
> codec {
> ...
> => clocks = <&xxx>;
> };
> };
>
I've seen bindings that have the 'clocks' property at the top
level and the appropriate 'clock-names' property to relate the
clocks to a subnode.
sound_soc {
clocks = <&xxx>, <&xxx>;
clock-names = "cpu", "codec";
...
cpu {
...
};
codec {
...
};
};
Then the subnodes call clk_get() with the top level device and
the name of their node and things match up. I suppose this
binding is finalized though, so we can't really do that?
I see that the gpio framework has a similar design called
devm_get_gpiod_from_child(), so how about we add a
devm_get_clk_from_child() API? That would more closely match the
intent here, which is to restrict the clk_get() operation to
child nodes of the device passed as the first argument.
struct clk *devm_get_clk_from_child(struct device *dev,
const char *con_id,
struct device_node *child);
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
* [PATCH] drivers/of: Export phandle iterators
From: Robin Murphy @ 2016-11-23 19:06 UTC (permalink / raw)
To: devicetree, linux-kernel; +Cc: Rob Herring, Frank Rowand
Modular drivers may want to use of_for_each_phandle() - export its
constituent functions.
CC: Rob Herring <robh+dt@kernel.org>
CC: Frank Rowand <frowand.list@gmail.com>
Signed-off-by: Robin Murphy <robin.murphy@arm.com>
---
drivers/of/base.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/of/base.c b/drivers/of/base.c
index a0bccb54a9bd..92e35fe0189a 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1563,6 +1563,7 @@ int of_phandle_iterator_init(struct of_phandle_iterator *it,
return 0;
}
+EXPORT_SYMBOL_GPL(of_phandle_iterator_init);
int of_phandle_iterator_next(struct of_phandle_iterator *it)
{
@@ -1632,6 +1633,7 @@ int of_phandle_iterator_next(struct of_phandle_iterator *it)
return -EINVAL;
}
+EXPORT_SYMBOL_GPL(of_phandle_iterator_next);
int of_phandle_iterator_args(struct of_phandle_iterator *it,
uint32_t *args,
@@ -1649,6 +1651,7 @@ int of_phandle_iterator_args(struct of_phandle_iterator *it,
return count;
}
+EXPORT_SYMBOL_GPL(of_phandle_iterator_args);
static int __of_parse_phandle_with_args(const struct device_node *np,
const char *list_name,
--
2.10.2.dirty
^ permalink raw reply related
* Re: [PATCH v9 02/16] clk: qcom: Move all sdcc rcgs to use clk_rcg2_floor_ops
From: Stephen Boyd @ 2016-11-23 19:00 UTC (permalink / raw)
To: Ritesh Harjani
Cc: ulf.hansson, linux-mmc, adrian.hunter, andy.gross, shawn.lin,
devicetree, linux-clk, david.brown, linux-arm-msm, georgi.djakov,
alex.lemberg, mateusz.nowak, Yuliy.Izrailov, asutoshd,
david.griego, stummala, venkatg, rnayak, pramod.gurav, jeremymc
In-Reply-To: <1479710246-26676-3-git-send-email-riteshh@codeaurora.org>
On 11/21, Ritesh Harjani wrote:
> From: Rajendra Nayak <rnayak@codeaurora.org>
>
> The sdcc driver for msm8996/msm8916/msm8974/msm8994 and apq8084
> expects a clk_set_rate() on the sdcc rcg clk to set
> a floor value of supported clk rate closest to the requested
> rate, by looking up the frequency table.
> So move all the sdcc rcgs on all these platforms to use the
> newly introduced clk_rcg2_floor_ops
>
> Signed-off-by: Rajendra Nayak <rnayak@codeaurora.org>
> Signed-off-by: Ritesh Harjani <riteshh@codeaurora.org>
> Signed-off-by: Jeremy McNicoll <jeremymc@redhat.com>
> ---
Applied to clk-next
--
Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum,
a Linux Foundation Collaborative Project
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox