summaryrefslogtreecommitdiffstats
path: root/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c
blob: 7eeea721a5ba05429b6974017e94b24c30beba8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
/***************************************************************************
 *             __________               __   ___.
 *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
 *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
 *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
 *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
 *                     \/            \/     \/    \/            \/
 *
 * Copyright (C) 2013 Lorenzo Miori
 *
 * 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.
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 ****************************************************************************/

#include <sys/ioctl.h>
#include <fcntl.h>
#include <stdio.h>
#include <unistd.h>

#include "config.h"
#include "kernel.h"
#include "powermgmt.h"
#include "power.h"
#include "adc.h"
#include "radio-ypr.h"
#include "pmu-ypr1.h"
#include "ioctl-ypr1.h"
#include "system.h"

#define MAX17040_VCELL          0x02
#define MAX17040_SOC            0x04
#define MAX17040_MODE           0x06
#define MAX17040_VERSION        0x08
#define MAX17040_RCOMP          0x0C
#define MAX17040_COMMAND        0xFE

static int max17040_dev = -1;

void max17040_init(void)
{
    max17040_dev = open("/dev/r1Batt", O_RDONLY);
    if (max17040_dev < 0)
        printf("/dev/r1Batt open error!");
}

void max17040_close(void)
{
    if (max17040_dev >= 0)
        close(max17040_dev);
}

#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE
const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
{
    3470
};

/* the OF shuts down at this voltage */
const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
{
    3450
};

/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
{
    { 3450, 3502, 3550, 3587, 3623, 3669, 3742, 3836, 3926, 4026, 4200 }
};
#endif

#if CONFIG_CHARGING
/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
const unsigned short const percent_to_volt_charge[11] =
{
      3450, 3670, 3721, 3751, 3782, 3821, 3876, 3941, 4034, 4125, 4200
};

unsigned int power_input_status(void)
{
    unsigned status = POWER_INPUT_NONE;
    if (pmu_ioctl(MAX8819_IOCTL_IS_EXT_PWR, NULL) > 0)
        status = POWER_INPUT_MAIN_CHARGER;
    return status;
}

#endif /* CONFIG_CHARGING */

/* Returns battery voltage from MAX17040 VCELL ADC [millivolts steps],
 * adc returns voltage in 1.25mV steps */
/*
 * TODO this would be interesting to be mixed with battery percentage, for information
 * and completition purpouses
 */
#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE
int _battery_voltage(void)
{
    int level = 4000;
    max17040_request ret = { .addr = 2, .reg1 = 0, .reg2 = 0 };
    if (ioctl(max17040_dev, MAX17040_READ_REG, &ret) >= 0)
    {
        int step = (ret.reg1 << 4) | (ret.reg2 >> 4);
        level = step + (step >> 2);
    }
    return level;
}
#elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE
int _battery_level(void)
{
    int level = 100;
    max17040_request ret = { .addr = 4, .reg1 = 0, .reg2 = 0 };
    if (ioctl(max17040_dev, MAX17040_READ_REG, &ret) >= 0)
        level = MIN(ret.reg1, 100);
    return level;
}
#endif

bool charging_state(void)
{
    int ret = pmu_ioctl(MAX8819_IOCTL_GET_CHG_STATUS, NULL);
    if (ret == PMU_FULLY_CHARGED)
        return true;
    return false;
}

#if CONFIG_TUNER
static bool tuner_on = false;

bool tuner_power(bool status)
{
    if (status != tuner_on)
    {
        tuner_on = status;
        status = !status;
        if (tuner_on)
            radiodev_open();
        else
            radiodev_close();
    }

    return status;
}

bool tuner_powered(void)
{
    return tuner_on;
}
#endif /* #if CONFIG_TUNER */