This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Linux/BQ25898D: BQ25898D

Part Number: BQ25898D
Other Parts Discussed in Thread: BQ25890, , BQ25898

Tool/software: Linux

Hi,

we have a bq25898D that we have connected to a Variscite SD410 devkit board running Linaro 4.4.9.  We connected it to our board over an i2c line and verified its presence with i2cdetect.  We looked at the drivers available in mainline, and we found bq25890_charger.c.  We build it as a .ko and loaded it via insmod, and when we loaded it, we got the following syslog message on the console.

[  710.815822] bq25890-charger 1-006a: Chip with ID=2, not supported!

The bq25898D has ID 3.  After looking through the code of the driver, I could easily remove the if-statement check to allow the probe function to continue, but even then we would still need to modify the driver because of some differences of the registers between the bq25898D and bq25890, namely REG01, REG03, and REG0A.  For REG01, we would just want to disable any writes because the bq25898D comes up with the values we need by default.  As long as those values don't change, that works for us.  The differences w.r.t. REG03 and REG0A vary only slightly and don't matter to us.

My questions:

(1) Does a driver exist written specifically for the bq25898D that runs on kernel 4.4.9 ?  If so, how can I get it?

(2) If a driver specifically for the bq25898D does not exist, do I need to know of any land mines or gotchas when modifying the bq25890_charger.c driver to accept a chip with ID=3 and refrain from doing any writes to REG01?

Thanks,

Brian

  • We do not have bq25898D driver. The closest drive is that of bq25898. The key differences between the two devices are bq25898D use D+/D- for input limit detection while bq25898 use PSEL. The drivers are located at https://github.com/tibms?tab=repositories. Hope the information helps. Thanks!

  • Hi Ning,

    have you tried to compile this driver against the Linux 4.4.9 kernel?  If not, which kernel did you use?  My attempt against 4.4.9 to build this driver failed.  See attachment.  It has the Makefile I used and the compilation errors.

    Thanks,

    Brian

    ning-archive1.zip

  • Hi Brian,

    The kernel version for which the driver given seems to be old, mostly 2.6.x series which TI has. You need to port the driver to latest kernel.
  • Hi Brian,

    I just now checked till 4.0, struct power_supply was the structure. Later they have split it into struct power_supply_desc and moved them into it

    Can you try whichever variable is not in power_supply, change them as
    e.g. bq->usb.num_properties into

    struct power_supply ps = bq->usb

    ps.desc.num_properties= ARRAY_SIZE(bq2589x_charger_props);

    I have not tested. Just a way to see if it is working.

  • Hi Dwarakesh,

    I attempted to run with a modified version of the bq25890_charger.c, since it resides within mainline.  I only needed to make some minor modifications to successfully build.  However, when I attempt load the .ko I get this error message.

    [10726.835113] bq25890-charger 1-006a: Could not probe irq pin.

    [10726.840166] bq25890-charger 1-006a: No irq resource found.

    [10726.846329] bq25890-charger: probe of 1-006a failed with error -2

    The function call to devm_gpiod_get_index() fails, and I'm not sure why.

    FWIW, here's a snippet of my device tree config.

    blsp_i2c6: i2c@78ba000 {

    ...

    bq25890@6a {

    compatible = "ti,bq25890";
    reg = <0x6a>;
    ti,battery-regulation-voltage = <4200000>;
    ti,charge-current = <1000000>;
    ti,termination-current = <50000>;
    ti,precharge-current = <128000>;
    ti,minimum-sys-voltage = <3600000>;
    ti,boost-voltage = <5000000>;
    ti,boost-max-current = <1000000>;
    ti,use-ilim-pin;
    ti,thermal-regulation-threshold = <120>;
    };

    };

    Do you think it's better to pursue to the bq25890 driver route or the bq25898 route.  The latter seems like a lot more work if this GPIO error is easily resolved.

     

  • Hi Brian,

    It looks like it is expecting a dtsi entry with bq25890_irq. Better would be to try above driver, since it is given by a TI person.
  • Hi Brian,

    It looks like there is a INT pint that can be connected to host. I think you need to provide that GPIO to which INT pin is connected in device tree with bq25890_irq name, I guess.
  • I will give porting the bq25898 driver to 4.4.9 a try. I found as much as you did when I searched through free electrons (i.e. kernel source online). For the meantime, I think I still need to resolve the device tree matter you raised. We connected the chip to GPIO 62, but I don't know what the syntax for assigning that to an IRQ label would be for a device tree. Do you happen to know it? I'm reading through Linux device tree doc, but I haven't found something that resembles doing that exactly.

    Thanks.
  • Hi Brian,

    Have you looked into this Document: Documentation/gpio/board.txt

  • Yes, as well as Documentation/devicetree/bindings/interrupt-controller/interrupts.txt, but I don't see anything that associates an IRQ label with a particular GPIO interrupt pin, at least not in a syntax compliant sample.

    Does TI have some working example of a device tree config for its BQ25898 driver?

  • Hi Brian,

    Can you show(dts and the code erro logs as you show) what you have tried ?
  • Given prior comments w.r.t. the bq25890 driver, I have dropped efforts of working with that. I have made a first attempt at porting it to 4.4.9. It compiles as an out-of-tree module, but it has an unresolved symbol that I believe to resolve I must place the module in-tree. I am currently trying to get it to build in-tree as I writ this. Despite making the changes to add it to tree, the make process keeps skipping it. I'm trying to figure out why right now.

    For once I get the in-tree build to succeed, this is the dts config I'm am using. It comes straight from the github page for the bq2589x driver.

    bq25898d@6a {
    compatible = "ti,bq2589x-1";
    reg = <0x6a>;

    ti,bq2589x,charge-voltage = <4208>;
    ti,bq2589x,charge-current = <2048>;
    ti,bq2589x,term-current = <256>;

    ti,bq2589x,enable-auto-dpdm;
    ti,bq2589x,enable-termination;
    ti,bq2589x,enable-ico;
    ti,bq2589x,use-absolute-vindpm;

    ti,bq2589x,vbus-volt-high-level = <8700>;/* tune adapter to output 9v */
    ti,bq2589x,vbus-volt-low-level = <4400>;/* tune adapter to output 5v */
    ti,bq2589x,vbat-min-volt-to-tuneup = <3000>;
    };

    Note that it has no reference any GPIO pin numbers or IRQ values.
  • It successfully builds in-tree now, and I've booted with the driver build into that image. It aborts upon startup, in the driver's probe function. I commented the probe function's contents out except for a single printk, recompiled, re-imaged, and rebooted. The same abort happens, and the printk never makes it into the syslog (dmesg). This makes me suspect something missing or wrongly formatted in the device tree required to simply invoke the probe method.

    FWIW, here's some output from the syslog.

    [ 4.679845] bq2589x_charger_init, bq2589x_charger2_driver register successfully!
    [ 4.683811] bq2589x-1 1-006a: bq2589x_charger1_probe: charger device bq25898D detected, revision:1
    [ 4.709686] Unable to handle kernel NULL pointer dereference at virtual address 00000000
    [ 4.709844] pgd = ffffffc000e0f000
    [ 4.716932] [00000000] *pgd=000000008eb06003, *pud=000000008eb06003, *pmd=000000008eb07003, *pte=00e800000b000707
    [ 4.730208] Internal error: Oops: 96000045 [#1] PREEMPT SMP
    [ 4.730261] Modules linked in:
    [ 4.730336] CPU: 2 PID: 1 Comm: swapper/0 Not tainted 4.4.9-linaro-lt-qcom #5
    [ 4.730353] Hardware name: Variscite VAR-SD410CustomBoard (DT)
    [ 4.730379] task: ffffffc00eb68000 ti: ffffffc00eb70000 task.ti: ffffffc00eb70000
    [ 4.730530] PC is at bq2589x_charger1_probe+0x154/0x58c
    [ 4.730537] LR is at bq2589x_charger1_probe+0x130/0x58c
    ...
    [ 4.731301] Call trace:
    [ 4.731316] [<ffffffc0005e1c14>] bq2589x_charger1_probe+0x154/0x58c
    [ 4.731385] [<ffffffc0005949d8>] i2c_device_probe+0x184/0x23c
    [ 4.731546] [<ffffffc00047e2a4>] driver_probe_device+0x21c/0x450
    [ 4.731561] [<ffffffc00047e574>] __driver_attach+0x9c/0xa0
    [ 4.731590] [<ffffffc00047c1b0>] bus_for_each_dev+0x58/0x98
    [ 4.731607] [<ffffffc00047dc04>] driver_attach+0x20/0x28
    [ 4.731619] [<ffffffc00047d76c>] bus_add_driver+0x1ec/0x290
    [ 4.731642] [<ffffffc00047edfc>] driver_register+0x68/0x108
    [ 4.731685] [<ffffffc0005964d0>] i2c_register_driver+0x34/0x98
    [ 4.731708] [<ffffffc000c6970c>] bq2589x_charger_init+0x88/0xc4
    [ 4.731781] [<ffffffc0000829b4>] do_one_initcall+0xc8/0x1c4
    [ 4.731870] [<ffffffc000c41af0>] kernel_init_freeable+0x150/0x1f4
    [ 4.731970] [<ffffffc000882894>] kernel_init+0x10/0xd8
    [ 4.732030] [<ffffffc000085c50>] ret_from_fork+0x10/0x40
    [ 4.732073] Code: a9067fbf f9002fb3 90002d81 9110e021 (f9000001)
    [ 5.230295] ---[ end trace 0000000000000001 ]---
  • Hi Brian,

    Can you add logs inside probe function. One of the pointers is NULL in it.
  • Hi, in the kernel trace in my previous post, the probe method had printk calls added to it, the very first of which executed as the first instruction of the function.  That's why I suspect a problem within the device tree file.

    -Brian

  • Hi Brian,

    I do the following to debug a kernel crash.
    1. Enable -g option in kernel Makefile
    2. Build the source and run to see the crash log
    3. Check PC : bq2589x_charger1_probe+0x154/0x58c
    4. Will note that crash offset is 0x154 from the start of function bq2589x_charger1_probe
    5. arm-linux*-objdump -Sd drivers/power/bq2589x_charger.o (assuming the source file is bq2589x_charger.c and built with same object file name)
    6. Go to the function bq2589x_charger1_probe. From function starting address (e.g. 0x123000) add 0x154 (e.g. 0x123154)
    7. Above 0x123154 line would give the line that crashed. Then check the variables in that line to verify if they are NULL.
  • Hi Dwarakesh,

    (1)

    first, I stumbled across something that I think I should explicitly state just to make sure we're on the same page.  I cloned this repo for the driver.

    I have also found this driver.

    They both look about the same in terms of age, and each one's sample device tree has an example for the BQ25898D.  Does TI recommend one of these over the other?

    (2)

    I found out why the syslog did not include any of my printk messages.  I had initially created an out-of-tree build before making an in-tree build of this driver, and I had mistakenly modified the out-of-tree source while building the in-tree source.  I now have that resolved and found the cause of the NULL pointer exception in the stack trace previously posted.  However, after done some more debugging, I have another one.

    [    4.697776] bq2589x-1 1-006a: bq2589x_charger1_probe:irq = 95

    [    4.706432] Unable to handle kernel NULL pointer dereference at virtual address 00000002

    ...

    [    4.803500] PC is at i2c_smbus_read_byte_data+0x10/0x3c

    [    4.803569] LR is at bq2589x_read_byte.isra.4+0x44/0xa0

    ...

    [    5.652932] [<ffffffc000085428>] el1_da+0x18/0x70

    [    5.652990] [<ffffffc0005e073c>] bq2589x_read_byte.isra.4+0x50/0xac

    [    5.653034] [<ffffffc0005e0cd0>] bq2589x_get_vbus_type+0x1c/0x3c

    [    5.653037] [<ffffffc0005e0df8>] bq2589x_usb_get_property+0x20/0xa8

    [    5.653056] [<ffffffc0005dc3f8>] power_supply_get_property+0x20/0x30

    [    5.653087] [<ffffffc0005dda48>] power_supply_update_leds+0x2c/0x190

    [    5.653109] [<ffffffc0005dcaa4>] power_supply_changed_work+0x6c/0xdc

    [    5.653159] [<ffffffc0000cea44>] process_one_work+0x138/0x304

    [    5.653194] [<ffffffc0000ced70>] worker_thread+0x160/0x440

    [    5.653205] [<ffffffc0000d42ac>] kthread+0xe0/0xf4

    [    5.653235] [<ffffffc000085c50>] ret_from_fork+0x10/0x40

    The bq->client member data points to NULL at this location in the source.

    static int bq2589x_read_byte(struct bq2589x *bq, u8 *data, u8 reg)
    {
    int ret;

    mutex_lock(&bq2589x_i2c_lock);
    ret = i2c_smbus_read_byte_data(bq->client, reg);

    So the i2c_set_clientdata(client, bq) call in bq2589x_charger1_probe() does not seem to actually set that data member.

    static int bq2589x_charger1_probe(struct i2c_client *client,
    const struct i2c_device_id *id)
    {

    ...

    bq->dev = &client->dev;

    bq->client = client;
    i2c_set_clientdata(client, bq);

    That's where I am at this point.  But before pursuing #2 any further, I thought I should check in on #1 first.

    Thanks,

    Brian

  • Hi Brian,

    Sorry, I am not aware of it. Hope some TI representative replies on it. But I am not sure if D stands for dual. May be you can give a try of all the drivers available till you get a reply here.
  • I've ported the bq25898_dual driver to Linaro 4.4.9.  It successfully loads, but unfortunately it consumes the console with syslog messages such that it makes the console unusable. E.g.

    ** 9 printk messages dropped ** [   30.236967] systemd-journald[1493]: /dev/kmsg buffer overrun, some messages lost.

    I have observed similar behavior with the BQ27421-D after patching its drivers to make it function on Linaro 4.4.9.  For reference, I have two open cases for that chip.

    However, in the case of the BQ25898D, I haven't confirmed that it is performing its core duties  Since this module depends on an external symbol that the kernel build process only exports when built in-tree, I can't build this as a .ko and insert it after initiating a wireless connection.  I don't have wired network support.  I've tried adding a script to /etc/init.d to initiate the wireless connection, but to no avail.  I also tried blacklisting the driver at boot time so that I could make ssh available before loading the driver, but that hasn't worked thus far either.

  • I have found the answer to the syslog overflow problem.  Apparently, kernel config items can cause this with the presence of an I2C or power supply device, the bq25898d being both of those.

    CONFIG_POWER_SUPPLY_DEBUG
    CONFIG_I2C_DEBUG_CORE

    This URL indicates that to avoid this disable one of those two config items.  I only had CONFIG_POWER_SUPPLY_DEBUG enabled, and the problem existed.  I had to disable it while already having CONFIG_I2C_DEBUG_CORE disabled to get rid of the problem.

    The driver I ported, bq25898_dual.c aborts upon system shutdown, i.e. when the system unregisters the driver, so I still haven't resolved this issue entirely.

  • Hi Brian,

    Good to hear you have made progress. Thanks for replying the fix here for the over logging messages.
  • BTW, the repo for the BQ25898 driver is empty, except for a single text file.

    github.com/.../bq25898