All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Ivan T. Ivanov" <iivanov@mm-sol.com>
To: Bjorn Andersson <bjorn@kryo.se>
Cc: Rob Herring <robh+dt@kernel.org>, Pawel Moll <pawel.moll@arm.com>,
	Mark Rutland <mark.rutland@arm.com>,
	Ian Campbell <ijc+devicetree@hellion.org.uk>,
	Kumar Gala <galak@codeaurora.org>,
	Samuel Ortiz <sameo@linux.intel.com>,
	Lee Jones <lee.jones@linaro.org>,
	Stanimir Varbanov <svarbanov@mm-sol.com>,
	"devicetree@vger.kernel.org" <devicetree@vger.kernel.org>,
	"linux-kernel@vger.kernel.org" <linux-kernel@vger.kernel.org>,
	linux-arm-msm <linux-arm-msm@vger.kernel.org>
Subject: Re: [PATCH] mfd: qcom-spmi-pmic: Add support for more chips versions
Date: Fri, 07 Nov 2014 17:33:10 +0200	[thread overview]
Message-ID: <1415374390.26058.1.camel@mm-sol.com> (raw)
In-Reply-To: <CAJAp7OgPGhM=EnMNU2JfjG6Qb-EiWSPSRyZWGicSPmpicBQW7g@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 2421 bytes --]


On Thu, 2014-11-06 at 08:55 -0800, Bjorn Andersson wrote:
> On Wed, Nov 5, 2014 at 11:54 PM, Ivan T. Ivanov <iivanov@mm-sol.com> wrote:
> > On Wed, 2014-11-05 at 17:36 -0800, Bjorn Andersson wrote:
> > > On Wed, Nov 5, 2014 at 10:31 AM, Ivan T. Ivanov <iivanov@mm-sol.com> wrote:
> [..]
> > > > Some of the child device drivers have to know PMIC chip revision.
> > > > 
> > > 
> > > So your plan is to have a strstr(parent->compatible, "-v2") there?
> > 
> > Actually also PMIC subtype (pm8841, pm8226...) is also required, so
> > the plan is to have something like this:
> > 
> > {
> >         static const struct of_device_id pmic_match_table[] = {
> >                 { .compatible = "qcom,pm8941-v1.0" },
> >                 { .compatible = "qcom,pm8841-v0.0" },
> >                 { }
> > 
> >         };
> > 
> >         const struct of_device_id *match;
> > 
> >         match = of_match_device(pmic_match_table, pdev->dev.parent);
> >         if (match) {
> >                 dev_info(&pdev->dev, "%s chip detected\n", match->compatible);
> >         }
> > }
> > 
> 
> To me this is a hack, you should not alter the devicetree to make it
> "better express the hardware". Either you know these things from boot
> and they go in device tree, or you can probe them and they should not
> go in device tree.
> 
> If you really need these values you should expose them through some api.

I would like to avoid compile time dependency between these drivers.
There are several precedents of using of_update_property() for enhancing
compatible property already.  

> 
> > > Could you be a little bit more elaborate on what you're trying to do
> > > and which child devices that might be?
> > 
> > For example ADC drivers are required temperature compensation based
> > on PMIC variant and chip manufacturer.
> > 
> 
> I see, is that compensation of any practical value? Or is the
> compensation of academic proportions?

It depends of what you mean by academic :-). Attached file have test
application which dump difference between non compensated and compensated
values for different temperature, manufacture and input value.

Output format of the program is:
Column 1: manufacturer GF=0, SMIC=1, TSMC=2
Column 2: chip revision
Column 3: die temperature in mili deg Celsius 
Column 4: input for compensation in micro Volts
Column 5: compensated result in micro Volts
Column 6: difference in micro Volts


Regards,
Ivan

[-- Attachment #2: temperature-compensation-check.c --]
[-- Type: text/x-csrc, Size: 14107 bytes --]


#include <stdio.h>

/* SW index's for PMIC type and version used by QPNP VADC and IADC */
#define REV_ID_8941_3_1	1
#define REV_ID_8026_1_0	2
#define REV_ID_8026_2_0	3
#define REV_ID_8110_1_0	4
#define REV_ID_8026_2_1	5
#define REV_ID_8110_2_0	6
#define REV_ID_8026_2_2	7
#define REV_ID_8941_3_0	8
#define REV_ID_8941_2_0	9
#define REV_ID_8916_1_0	10
#define REV_ID_8916_1_1	11
#define REV_ID_8916_2_0	12

#define FACTORY_GF 		0
#define FACTORY_SMIC		1
#define FACTORY_TSMC		2

#define VBAT_COEFF_1	3000
#define VBAT_COEFF_2	45810000
#define VBAT_COEFF_3	100000
#define VBAT_COEFF_4	3500
#define VBAT_COEFF_5	80000000
#define VBAT_COEFF_6	4400
#define VBAT_COEFF_7	32200000
#define VBAT_COEFF_8	3880
#define VBAT_COEFF_9	5770
#define VBAT_COEFF_10	3660
#define VBAT_COEFF_11	5320
#define VBAT_COEFF_12	8060000
#define VBAT_COEFF_13	102640000
#define VBAT_COEFF_14	22220000
#define VBAT_COEFF_15	83060000
#define VBAT_COEFF_16	2810
#define VBAT_COEFF_17	5260
#define VBAT_COEFF_18	8027
#define VBAT_COEFF_19	2347
#define VBAT_COEFF_20	6043
#define VBAT_COEFF_21	1914
#define VBAT_OFFSET_SMIC	9446
#define VBAT_OFFSET_GF	9441
#define OCV_OFFSET_SMIC	4596
#define OCV_OFFSET_GF	5896
#define VBAT_COEFF_22	6800
#define VBAT_COEFF_23	3500
#define VBAT_COEFF_24	4360
#define VBAT_COEFF_25	8060
#define VBAT_COEFF_26	7895
#define VBAT_COEFF_27	5658
#define VBAT_COEFF_28	5760
#define VBAT_COEFF_29	7900
#define VBAT_COEFF_30	5660
#define VBAT_COEFF_31	3620
#define VBAT_COEFF_32	1230
#define VBAT_COEFF_33	5760
#define VBAT_COEFF_34	4080
#define VBAT_COEFF_35	7000
#define VBAT_COEFF_36	3040
#define VBAT_COEFF_37	3850
#define VBAT_COEFF_38	5000
#define VBAT_COEFF_39	2610
#define VBAT_COEFF_40	4190
#define VBAT_COEFF_41	5800
#define VBAT_COEFF_42	2620
#define VBAT_COEFF_43	4030
#define VBAT_COEFF_44	3230
#define VBAT_COEFF_45	3450
#define VBAT_COEFF_46	2120
#define VBAT_COEFF_47	3560
#define VBAT_COEFF_48	2190

static long
qpnp_ocv_comp(int version, int factory, long result, long die_temp)
{
    long temp_var = 0, offset = 0;

    if (version == REV_ID_8026_2_2) {
        if (die_temp > 25000)
            return result;
    }

    switch (version) {
        case REV_ID_8941_3_1:
            switch (factory) {
                case FACTORY_TSMC:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_4));
                    break;
                default:
                case FACTORY_GF:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_1));
                    break;
            }
            break;
        case REV_ID_8026_1_0:
            switch (factory) {
                case FACTORY_TSMC:
                    temp_var = (((die_temp * (-VBAT_COEFF_10))
                                 - VBAT_COEFF_14));
                    break;
                default:
                case FACTORY_GF:
                    temp_var = (((die_temp * (-VBAT_COEFF_8))
                                 + VBAT_COEFF_12));
                    break;
            }
            break;
        case REV_ID_8026_2_0:
        case REV_ID_8026_2_1:
            switch (factory) {
                case FACTORY_TSMC:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_10));
                    break;
                default:
                case FACTORY_GF:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_8));
                    break;
            }
            break;
        case REV_ID_8026_2_2:
            switch (factory) {
                case FACTORY_TSMC:
                    result -= VBAT_COEFF_22;
                    temp_var = (die_temp - 25000) * VBAT_COEFF_24;
                    break;
                default:
                case FACTORY_GF:
                    result -= VBAT_COEFF_22;
                    temp_var = (die_temp - 25000) * VBAT_COEFF_25;
                    break;
            }
            break;
        case REV_ID_8110_2_0:
            switch (factory) {
                case FACTORY_SMIC:
                    result -= OCV_OFFSET_SMIC;
                    if (die_temp < 25000)
                        temp_var = VBAT_COEFF_18;
                    else
                        temp_var = VBAT_COEFF_19;
                    temp_var = (die_temp - 25000) * temp_var;
                    break;
                default:
                case FACTORY_GF:
                    result -= OCV_OFFSET_GF;
                    if (die_temp < 25000)
                        temp_var = VBAT_COEFF_20;
                    else
                        temp_var = VBAT_COEFF_21;
                    temp_var = (die_temp - 25000) * temp_var;
                    break;
            }
            break;
        case REV_ID_8916_1_0:
            switch (factory) {
                case FACTORY_SMIC:
                    if (die_temp < 25000)
                        temp_var = VBAT_COEFF_26;
                    else
                        temp_var = VBAT_COEFF_27;
                    temp_var = (die_temp - 25000) * temp_var;
                    break;
                default:
                case FACTORY_GF:
                    offset = OCV_OFFSET_GF;
                    if (die_temp < 25000)
                        temp_var = VBAT_COEFF_26;
                    else
                        temp_var = VBAT_COEFF_27;
                    temp_var = (die_temp - 25000) * temp_var;
                    break;
            }
            break;
        case REV_ID_8916_1_1:
            switch (factory) {
                    /* FAB_ID is zero */
                case FACTORY_GF:
                    if (die_temp < 25000)
                        temp_var = VBAT_COEFF_29;
                    else
                        temp_var = VBAT_COEFF_30;
                    temp_var = (die_temp - 25000) * temp_var;
                    break;
                    /* FAB_ID is non-zero */
                default:
                    if (die_temp < 25000)
                        temp_var = VBAT_COEFF_31;
                    else
                        temp_var = (-VBAT_COEFF_32);
                    temp_var = (die_temp - 25000) * temp_var;
                    break;
            }
            break;
        case REV_ID_8916_2_0:
            switch (factory) {
                case FACTORY_SMIC:
                    offset = (-VBAT_COEFF_38);
                    if (die_temp < 0)
                        temp_var = die_temp * VBAT_COEFF_36;
                    else if (die_temp > 40000)
                        temp_var = ((die_temp - 40000) * (-VBAT_COEFF_37));
                    break;
                case FACTORY_TSMC:
                    if (die_temp < 10000)
                        temp_var = ((die_temp - 10000) * VBAT_COEFF_41);
                    else if (die_temp > 50000)
                        temp_var = ((die_temp - 50000) * (-VBAT_COEFF_42));
                    break;
                default:
                case FACTORY_GF:
                    if (die_temp < 20000)
                        temp_var = ((die_temp - 20000) * VBAT_COEFF_45);
                    else if (die_temp > 40000)
                        temp_var = ((die_temp - 40000) * (-VBAT_COEFF_46));
                    break;
            }
            break;
        default:
            temp_var = 0;
            break;
    }

    temp_var = temp_var / VBAT_COEFF_3;

    temp_var = 1000000 + temp_var;

    result = result * temp_var;

    if (offset)
        result -= offset;

    result = result / 1000000;

    return result;
}

static long
qpnp_vbat_sns_comp(int version, int factory, long result, long die_temp)
{
    long temp_var = 0, offset = 0;

    if (version != REV_ID_8941_3_1) {
        /* min(die_temp_c, 60_degC) */
        if (die_temp > 60000)
            die_temp = 60000;
    }

    switch (version) {
        case REV_ID_8941_3_1:
            switch (factory) {
                case FACTORY_TSMC:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_1));
                    break;
                default:
                case FACTORY_GF:
                    /* min(die_temp_c, 60_degC) */
                    if (die_temp > 60000)
                        die_temp = 60000;
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_1));
                    break;
            }
            break;
        case REV_ID_8026_1_0:
            switch (factory) {
                case FACTORY_TSMC:
                    temp_var = (((die_temp * (-VBAT_COEFF_11))
                                 + VBAT_COEFF_15));
                    break;
                default:
                case FACTORY_GF:
                    temp_var = (((die_temp * (-VBAT_COEFF_9))
                                 + VBAT_COEFF_13));
                    break;
            }
            break;
        case REV_ID_8026_2_0:
        case REV_ID_8026_2_1:
            switch (factory) {
                case FACTORY_TSMC:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_11));
                    break;
                default:
                case FACTORY_GF:
                    temp_var = ((die_temp - 25000) * (-VBAT_COEFF_9));
                    break;
            }
            break;
        case REV_ID_8026_2_2:
            switch (factory) {
                case FACTORY_TSMC:
                    result -= VBAT_COEFF_23;
                    temp_var = 0;
                    break;
                default:
                case FACTORY_GF:
                    result -= VBAT_COEFF_23;
                    temp_var = 0;
                    break;
            }
            break;
        case REV_ID_8110_2_0:
            switch (factory) {
                case FACTORY_SMIC:
                    result -= VBAT_OFFSET_SMIC;
                    temp_var = ((die_temp - 25000) * (VBAT_COEFF_17));
                    break;
                default:
                case FACTORY_GF:
                    result -= VBAT_OFFSET_GF;
                    temp_var = ((die_temp - 25000) * (VBAT_COEFF_16));
                    break;
            }
            break;
        case REV_ID_8916_1_0:
            switch (factory) {
                case FACTORY_SMIC:
                    temp_var = ((die_temp - 25000) * (VBAT_COEFF_28));
                    break;
                default:
                case FACTORY_GF:
                    temp_var = ((die_temp - 25000) * (VBAT_COEFF_28));
                    break;
            }
            break;
        case REV_ID_8916_1_1:
            switch (factory) {
                    /* FAB_ID is zero */
                case FACTORY_GF:
                    temp_var = ((die_temp - 25000) * (VBAT_COEFF_33));
                    break;
                    /* FAB_ID is non-zero */
                default:
                    offset = VBAT_COEFF_35;
                    if (die_temp > 50000) {
                        temp_var = ((die_temp - 25000) * (VBAT_COEFF_34));
                    }
                    break;
            }
            break;
        case REV_ID_8916_2_0:
            switch (factory) {
                case FACTORY_SMIC:
                    if (die_temp < 0) {
                        temp_var = (die_temp * VBAT_COEFF_39);
                    } else if (die_temp > 40000) {
                        temp_var = ((die_temp - 40000) * (-VBAT_COEFF_40));
                    }
                    break;
                case FACTORY_TSMC:
                    if (die_temp < 10000)
                        temp_var = ((die_temp - 10000) * VBAT_COEFF_43);
                    else if (die_temp > 50000)
                        temp_var = ((die_temp - 50000) * (-VBAT_COEFF_44));
                    break;
                default:
                case FACTORY_GF:
                    if (die_temp < 20000)
                        temp_var = ((die_temp - 20000) * VBAT_COEFF_47);
                    else if (die_temp > 40000)
                        temp_var = ((die_temp - 40000) * (-VBAT_COEFF_48));
                    break;
            }
            break;
        default:
            temp_var = 0;
            break;
    }

    temp_var = temp_var / VBAT_COEFF_3;

    temp_var = 1000000 + temp_var;

    result = result * temp_var;

    if (offset)
        result -= offset;

    result = result / 1000000;

    return result;
}

int
main(void)
{
    long result, original, die_temp, diff;
    int version, factory;

    printf("==================================================================\n");
    printf("                         OCV Compensation                         \n");
    printf("==================================================================\n");

    for (factory = FACTORY_GF; factory <= FACTORY_TSMC; factory++) {

        for (version = REV_ID_8941_3_1; version <= REV_ID_8916_2_0; version++) {

            for (die_temp = 0; die_temp <= 100000; die_temp += 10000) {

                for (original = 0; original <= 1800000; original += 100000) {

                    result = qpnp_ocv_comp(version, factory, original, die_temp);

                    diff = result - original;

                    printf("%d\t%d\t%ld\t%ld\t%ld\t%ld\n", factory, version, die_temp, original, result, diff);
                }
            }
        }
    }

    printf("==================================================================\n");
    printf("                         VBAT Compensation                        \n");
    printf("==================================================================\n");

    for (factory = FACTORY_GF; factory <= FACTORY_TSMC; factory++) {

        for (version = REV_ID_8941_3_1; version <= REV_ID_8916_2_0; version++) {

            for (die_temp = 0; die_temp <= 100000; die_temp += 10000) {

                for (original = 0; original <= 1800000; original += 100000) {

                    result = qpnp_vbat_sns_comp(version, factory, original, die_temp);

                    diff = result - original;

                    printf("%d\t%d\t%ld\t%ld\t%ld\t%ld\n", factory, version, die_temp, original, result, diff);
                }
            }
        }
    }

    return 0;
}

  reply	other threads:[~2014-11-07 15:32 UTC|newest]

Thread overview: 24+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2014-11-04 13:33 [PATCH] mfd: qcom-spmi-pmic: Add support for more chips versions Ivan T. Ivanov
2014-11-04 14:56 ` Fabio Estevam
2014-11-04 15:17   ` Ivan T. Ivanov
     [not found] ` <1415108003-16387-1-git-send-email-iivanov-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-11-04 15:06   ` Stanimir Varbanov
2014-11-04 15:06     ` Stanimir Varbanov
2014-11-04 15:22     ` Ivan T. Ivanov
2014-11-04 15:26       ` Stanimir Varbanov
2014-11-04 15:49         ` Ivan T. Ivanov
2014-11-05 12:49 ` Andreas Färber
2014-11-05 13:50   ` Ivan T. Ivanov
2014-11-05 18:11 ` Bjorn Andersson
2014-11-05 18:31   ` Ivan T. Ivanov
     [not found]     ` <1415212271.14949.1.camel-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-11-06  1:36       ` Bjorn Andersson
2014-11-06  1:36         ` Bjorn Andersson
     [not found]         ` <CAJAp7OgXHGWQj7MWh51LTUdmZpgZc=6m=o-Az=z8QxR7yfrw7g-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org>
2014-11-06  7:54           ` Ivan T. Ivanov
2014-11-06  7:54             ` Ivan T. Ivanov
2014-11-06 16:55             ` Bjorn Andersson
2014-11-07 15:33               ` Ivan T. Ivanov [this message]
2014-11-07 15:40                 ` Ivan T. Ivanov
     [not found]                   ` <1415374852.26058.3.camel-NEYub+7Iv8PQT0dZR+AlfA@public.gmane.org>
2014-11-11 20:27                     ` Courtney Cavin
2014-11-11 20:27                       ` Courtney Cavin
2014-11-12  9:12                       ` Ivan T. Ivanov
2014-11-08  0:08             ` Gilad Avidov
2014-11-10  7:46               ` Ivan T. Ivanov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1415374390.26058.1.camel@mm-sol.com \
    --to=iivanov@mm-sol.com \
    --cc=bjorn@kryo.se \
    --cc=devicetree@vger.kernel.org \
    --cc=galak@codeaurora.org \
    --cc=ijc+devicetree@hellion.org.uk \
    --cc=lee.jones@linaro.org \
    --cc=linux-arm-msm@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=mark.rutland@arm.com \
    --cc=pawel.moll@arm.com \
    --cc=robh+dt@kernel.org \
    --cc=sameo@linux.intel.com \
    --cc=svarbanov@mm-sol.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.