mirror of
https://github.com/AsahiLinux/u-boot
synced 2024-11-28 15:41:40 +00:00
Merge git://git.denx.de/u-boot-dm
This commit is contained in:
commit
a5a5882611
73 changed files with 3347 additions and 503 deletions
|
@ -6,6 +6,15 @@ choice
|
|||
config TARGET_JETSON_TK1
|
||||
bool "NVIDIA Tegra124 Jetson TK1 board"
|
||||
|
||||
config TARGET_NYAN_BIG
|
||||
bool "Google/NVIDIA Nyan-big Chrombook"
|
||||
help
|
||||
Nyan Big is a Tegra124 clamshell board that is very similar
|
||||
to venice2, but it has a different panel, the sdcard CD and WP
|
||||
sense are flipped, and it has a different revision of the AS3722
|
||||
PMIC. The retail name is the Acer Chromebook 13 CB5-311-T7NN
|
||||
(13.3-inch HD, NVIDIA Tegra K1, 2GB).
|
||||
|
||||
config TARGET_VENICE2
|
||||
bool "NVIDIA Tegra124 Venice2"
|
||||
|
||||
|
@ -15,6 +24,7 @@ config SYS_SOC
|
|||
default "tegra124"
|
||||
|
||||
source "board/nvidia/jetson-tk1/Kconfig"
|
||||
source "board/nvidia/nyan-big/Kconfig"
|
||||
source "board/nvidia/venice2/Kconfig"
|
||||
|
||||
endif
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <tps6586x.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
|
@ -23,9 +24,13 @@
|
|||
#define VDD_TRANSITION_STEP 0x06 /* 150mv */
|
||||
#define VDD_TRANSITION_RATE 0x06 /* 3.52mv/us */
|
||||
|
||||
#define PMI_I2C_ADDRESS 0x34 /* chip requires this address */
|
||||
|
||||
int pmu_set_nominal(void)
|
||||
{
|
||||
int core, cpu, bus;
|
||||
struct udevice *bus, *dev;
|
||||
int core, cpu;
|
||||
int ret;
|
||||
|
||||
/* by default, the table has been filled with T25 settings */
|
||||
switch (tegra_get_chip_sku()) {
|
||||
|
@ -42,12 +47,18 @@ int pmu_set_nominal(void)
|
|||
return -1;
|
||||
}
|
||||
|
||||
bus = tegra_i2c_get_dvc_bus_num();
|
||||
if (bus == -1) {
|
||||
ret = tegra_i2c_get_dvc_bus(&bus);
|
||||
if (ret) {
|
||||
debug("%s: Cannot find DVC I2C bus\n", __func__);
|
||||
return -1;
|
||||
return ret;
|
||||
}
|
||||
tps6586x_init(bus);
|
||||
ret = i2c_get_chip(bus, PMI_I2C_ADDRESS, &dev);
|
||||
if (ret) {
|
||||
debug("%s: Cannot find DVC I2C chip\n", __func__);
|
||||
return ret;
|
||||
}
|
||||
|
||||
tps6586x_init(dev);
|
||||
tps6586x_set_pwm_mode(TPS6586X_PWM_SM1);
|
||||
return tps6586x_adjust_sm0_sm1(core, cpu, VDD_TRANSITION_STEP,
|
||||
VDD_TRANSITION_RATE, VDD_RELATION);
|
||||
|
|
|
@ -31,6 +31,7 @@ dtb-$(CONFIG_TEGRA) += tegra20-harmony.dtb \
|
|||
tegra30-tec-ng.dtb \
|
||||
tegra114-dalmore.dtb \
|
||||
tegra124-jetson-tk1.dtb \
|
||||
tegra124-nyan-big.dtb \
|
||||
tegra124-venice2.dtb
|
||||
dtb-$(CONFIG_ARCH_UNIPHIER) += \
|
||||
uniphier-ph1-sld3-ref.dtb \
|
||||
|
|
105
arch/arm/dts/cros-ec-keyboard.dtsi
Normal file
105
arch/arm/dts/cros-ec-keyboard.dtsi
Normal file
|
@ -0,0 +1,105 @@
|
|||
/*
|
||||
* Keyboard dts fragment for devices that use cros-ec-keyboard
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License version 2 as
|
||||
* published by the Free Software Foundation.
|
||||
*/
|
||||
|
||||
#include <dt-bindings/input/input.h>
|
||||
|
||||
&cros_ec {
|
||||
keyboard-controller {
|
||||
compatible = "google,cros-ec-keyb";
|
||||
keypad,num-rows = <8>;
|
||||
keypad,num-columns = <13>;
|
||||
google,needs-ghost-filter;
|
||||
|
||||
linux,keymap = <
|
||||
MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA)
|
||||
MATRIX_KEY(0x00, 0x02, KEY_F1)
|
||||
MATRIX_KEY(0x00, 0x03, KEY_B)
|
||||
MATRIX_KEY(0x00, 0x04, KEY_F10)
|
||||
MATRIX_KEY(0x00, 0x06, KEY_N)
|
||||
MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
|
||||
MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
|
||||
|
||||
MATRIX_KEY(0x01, 0x01, KEY_ESC)
|
||||
MATRIX_KEY(0x01, 0x02, KEY_F4)
|
||||
MATRIX_KEY(0x01, 0x03, KEY_G)
|
||||
MATRIX_KEY(0x01, 0x04, KEY_F7)
|
||||
MATRIX_KEY(0x01, 0x06, KEY_H)
|
||||
MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
|
||||
MATRIX_KEY(0x01, 0x09, KEY_F9)
|
||||
MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
|
||||
|
||||
MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
|
||||
MATRIX_KEY(0x02, 0x01, KEY_TAB)
|
||||
MATRIX_KEY(0x02, 0x02, KEY_F3)
|
||||
MATRIX_KEY(0x02, 0x03, KEY_T)
|
||||
MATRIX_KEY(0x02, 0x04, KEY_F6)
|
||||
MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)
|
||||
MATRIX_KEY(0x02, 0x06, KEY_Y)
|
||||
MATRIX_KEY(0x02, 0x07, KEY_102ND)
|
||||
MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
|
||||
MATRIX_KEY(0x02, 0x09, KEY_F8)
|
||||
|
||||
MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
|
||||
MATRIX_KEY(0x03, 0x02, KEY_F2)
|
||||
MATRIX_KEY(0x03, 0x03, KEY_5)
|
||||
MATRIX_KEY(0x03, 0x04, KEY_F5)
|
||||
MATRIX_KEY(0x03, 0x06, KEY_6)
|
||||
MATRIX_KEY(0x03, 0x08, KEY_MINUS)
|
||||
MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
|
||||
|
||||
MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
|
||||
MATRIX_KEY(0x04, 0x01, KEY_A)
|
||||
MATRIX_KEY(0x04, 0x02, KEY_D)
|
||||
MATRIX_KEY(0x04, 0x03, KEY_F)
|
||||
MATRIX_KEY(0x04, 0x04, KEY_S)
|
||||
MATRIX_KEY(0x04, 0x05, KEY_K)
|
||||
MATRIX_KEY(0x04, 0x06, KEY_J)
|
||||
MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
|
||||
MATRIX_KEY(0x04, 0x09, KEY_L)
|
||||
MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
|
||||
MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
|
||||
|
||||
MATRIX_KEY(0x05, 0x01, KEY_Z)
|
||||
MATRIX_KEY(0x05, 0x02, KEY_C)
|
||||
MATRIX_KEY(0x05, 0x03, KEY_V)
|
||||
MATRIX_KEY(0x05, 0x04, KEY_X)
|
||||
MATRIX_KEY(0x05, 0x05, KEY_COMMA)
|
||||
MATRIX_KEY(0x05, 0x06, KEY_M)
|
||||
MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)
|
||||
MATRIX_KEY(0x05, 0x08, KEY_SLASH)
|
||||
MATRIX_KEY(0x05, 0x09, KEY_DOT)
|
||||
MATRIX_KEY(0x05, 0x0b, KEY_SPACE)
|
||||
|
||||
MATRIX_KEY(0x06, 0x01, KEY_1)
|
||||
MATRIX_KEY(0x06, 0x02, KEY_3)
|
||||
MATRIX_KEY(0x06, 0x03, KEY_4)
|
||||
MATRIX_KEY(0x06, 0x04, KEY_2)
|
||||
MATRIX_KEY(0x06, 0x05, KEY_8)
|
||||
MATRIX_KEY(0x06, 0x06, KEY_7)
|
||||
MATRIX_KEY(0x06, 0x08, KEY_0)
|
||||
MATRIX_KEY(0x06, 0x09, KEY_9)
|
||||
MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT)
|
||||
MATRIX_KEY(0x06, 0x0b, KEY_DOWN)
|
||||
MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)
|
||||
|
||||
MATRIX_KEY(0x07, 0x01, KEY_Q)
|
||||
MATRIX_KEY(0x07, 0x02, KEY_E)
|
||||
MATRIX_KEY(0x07, 0x03, KEY_R)
|
||||
MATRIX_KEY(0x07, 0x04, KEY_W)
|
||||
MATRIX_KEY(0x07, 0x05, KEY_I)
|
||||
MATRIX_KEY(0x07, 0x06, KEY_U)
|
||||
MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)
|
||||
MATRIX_KEY(0x07, 0x08, KEY_P)
|
||||
MATRIX_KEY(0x07, 0x09, KEY_O)
|
||||
MATRIX_KEY(0x07, 0x0b, KEY_UP)
|
||||
MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
|
||||
>;
|
||||
};
|
||||
};
|
|
@ -16,7 +16,6 @@
|
|||
i2c2 = "/i2c@7000c400";
|
||||
i2c3 = "/i2c@7000c500";
|
||||
i2c4 = "/i2c@7000c700";
|
||||
i2c5 = "/i2c@7000d100";
|
||||
sdhci0 = "/sdhci@700b0600";
|
||||
sdhci1 = "/sdhci@700b0400";
|
||||
spi0 = "/spi@7000d400";
|
||||
|
|
365
arch/arm/dts/tegra124-nyan-big.dts
Normal file
365
arch/arm/dts/tegra124-nyan-big.dts
Normal file
|
@ -0,0 +1,365 @@
|
|||
/dts-v1/;
|
||||
|
||||
#include <dt-bindings/input/input.h>
|
||||
#include "tegra124.dtsi"
|
||||
|
||||
/ {
|
||||
model = "Acer Chromebook 13 CB5-311";
|
||||
compatible = "google,nyan-big", "nvidia,tegra124";
|
||||
|
||||
aliases {
|
||||
console = &uarta;
|
||||
i2c0 = "/i2c@7000d000";
|
||||
i2c1 = "/i2c@7000c000";
|
||||
i2c2 = "/i2c@7000c400";
|
||||
i2c3 = "/i2c@7000c500";
|
||||
i2c4 = "/i2c@7000c700";
|
||||
i2c5 = "/i2c@7000d100";
|
||||
rtc0 = "/i2c@0,7000d000/pmic@40";
|
||||
rtc1 = "/rtc@0,7000e000";
|
||||
sdhci0 = "/sdhci@700b0600";
|
||||
sdhci1 = "/sdhci@700b0400";
|
||||
spi0 = "/spi@7000d400";
|
||||
spi1 = "/spi@7000da00";
|
||||
usb0 = "/usb@7d000000";
|
||||
usb1 = "/usb@7d008000";
|
||||
};
|
||||
|
||||
memory {
|
||||
reg = <0x80000000 0x80000000>;
|
||||
};
|
||||
|
||||
serial@70006000 {
|
||||
/* Debug connector on the bottom of the board near SD card. */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
pwm@7000a000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
i2c@7000c000 {
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
|
||||
acodec: audio-codec@10 {
|
||||
compatible = "maxim,max98090";
|
||||
reg = <0x10>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(H, 4) GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
temperature-sensor@4c {
|
||||
compatible = "ti,tmp451";
|
||||
reg = <0x4c>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(I, 6) IRQ_TYPE_LEVEL_LOW>;
|
||||
|
||||
#thermal-sensor-cells = <1>;
|
||||
};
|
||||
};
|
||||
|
||||
i2c@7000c400 {
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
i2c@7000c500 {
|
||||
status = "okay";
|
||||
clock-frequency = <400000>;
|
||||
|
||||
tpm@20 {
|
||||
compatible = "infineon,slb9645tt";
|
||||
reg = <0x20>;
|
||||
};
|
||||
};
|
||||
|
||||
hdmi_ddc: i2c@7000c700 {
|
||||
status = "okay";
|
||||
clock-frequency = <100000>;
|
||||
};
|
||||
|
||||
i2c@7000d000 {
|
||||
status = "okay";
|
||||
clock-frequency = <400000>;
|
||||
|
||||
pmic: pmic@40 {
|
||||
compatible = "ams,as3722";
|
||||
reg = <0x40>;
|
||||
interrupts = <0 86 IRQ_TYPE_LEVEL_HIGH>;
|
||||
|
||||
ams,system-power-controller;
|
||||
|
||||
#interrupt-cells = <2>;
|
||||
interrupt-controller;
|
||||
|
||||
gpio-controller;
|
||||
#gpio-cells = <2>;
|
||||
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&as3722_default>;
|
||||
|
||||
as3722_default: pinmux {
|
||||
gpio0 {
|
||||
pins = "gpio0";
|
||||
function = "gpio";
|
||||
bias-pull-down;
|
||||
};
|
||||
|
||||
gpio1 {
|
||||
pins = "gpio1";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
gpio2_4_7 {
|
||||
pins = "gpio2", "gpio4", "gpio7";
|
||||
function = "gpio";
|
||||
bias-pull-up;
|
||||
};
|
||||
|
||||
gpio3_6 {
|
||||
pins = "gpio3", "gpio6";
|
||||
bias-high-impedance;
|
||||
};
|
||||
|
||||
gpio5 {
|
||||
pins = "gpio5";
|
||||
function = "clk32k-out";
|
||||
bias-pull-down;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spi@7000d400 {
|
||||
status = "okay";
|
||||
|
||||
cros_ec: cros-ec@0 {
|
||||
compatible = "google,cros-ec-spi";
|
||||
spi-max-frequency = <3000000>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(C, 7) IRQ_TYPE_LEVEL_LOW>;
|
||||
reg = <0>;
|
||||
|
||||
google,cros-ec-spi-msg-delay = <2000>;
|
||||
|
||||
i2c-tunnel {
|
||||
compatible = "google,cros-ec-i2c-tunnel";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
google,remote-bus = <0>;
|
||||
|
||||
charger: bq24735@9 {
|
||||
compatible = "ti,bq24735";
|
||||
reg = <0x9>;
|
||||
interrupt-parent = <&gpio>;
|
||||
interrupts = <TEGRA_GPIO(J, 0)
|
||||
GPIO_ACTIVE_HIGH>;
|
||||
ti,ac-detect-gpios = <&gpio
|
||||
TEGRA_GPIO(J, 0)
|
||||
GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
|
||||
battery: sbs-battery@b {
|
||||
compatible = "sbs,sbs-battery";
|
||||
reg = <0xb>;
|
||||
sbs,i2c-retry-count = <2>;
|
||||
sbs,poll-retry-count = <10>;
|
||||
power-supplies = <&charger>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spi@7000da00 {
|
||||
status = "okay";
|
||||
spi-max-frequency = <25000000>;
|
||||
|
||||
flash@0 {
|
||||
compatible = "winbond,w25q32dw";
|
||||
reg = <0>;
|
||||
};
|
||||
};
|
||||
|
||||
pmc@7000e400 {
|
||||
nvidia,invert-interrupt;
|
||||
nvidia,suspend-mode = <0>;
|
||||
nvidia,cpu-pwr-good-time = <500>;
|
||||
nvidia,cpu-pwr-off-time = <300>;
|
||||
nvidia,core-pwr-good-time = <641 3845>;
|
||||
nvidia,core-pwr-off-time = <61036>;
|
||||
nvidia,core-power-req-active-high;
|
||||
nvidia,sys-clock-req-active-high;
|
||||
};
|
||||
|
||||
hda@70030000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
sdhci@700b0000 { /* WiFi/BT on this bus */
|
||||
status = "okay";
|
||||
power-gpios = <&gpio TEGRA_GPIO(X, 7) GPIO_ACTIVE_HIGH>;
|
||||
bus-width = <4>;
|
||||
no-1-8-v;
|
||||
non-removable;
|
||||
};
|
||||
|
||||
sdhci@700b0400 { /* SD Card on this bus */
|
||||
status = "okay";
|
||||
cd-gpios = <&gpio TEGRA_GPIO(V, 2) GPIO_ACTIVE_LOW>;
|
||||
power-gpios = <&gpio TEGRA_GPIO(R, 0) GPIO_ACTIVE_HIGH>;
|
||||
wp-gpios = <&gpio TEGRA_GPIO(Q, 4) GPIO_ACTIVE_LOW>;
|
||||
bus-width = <4>;
|
||||
no-1-8-v;
|
||||
};
|
||||
|
||||
sdhci@700b0600 { /* eMMC on this bus */
|
||||
status = "okay";
|
||||
bus-width = <8>;
|
||||
no-1-8-v;
|
||||
non-removable;
|
||||
};
|
||||
|
||||
ahub@70300000 {
|
||||
i2s@70301100 {
|
||||
status = "okay";
|
||||
};
|
||||
};
|
||||
|
||||
usb@7d000000 { /* Rear external USB port. */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb-phy@7d000000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb@7d004000 { /* Internal webcam. */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb-phy@7d004000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb@7d008000 { /* Left external USB port. */
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
usb-phy@7d008000 {
|
||||
status = "okay";
|
||||
};
|
||||
|
||||
backlight: backlight {
|
||||
compatible = "pwm-backlight";
|
||||
|
||||
enable-gpios = <&gpio TEGRA_GPIO(H, 2) GPIO_ACTIVE_HIGH>;
|
||||
pwms = <&pwm 1 1000000>;
|
||||
|
||||
default-brightness-level = <224>;
|
||||
brightness-levels =
|
||||
< 0 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 154 155 156 157 158 159
|
||||
160 161 162 163 164 165 166 167
|
||||
168 169 170 171 172 173 174 175
|
||||
176 177 178 179 180 181 182 183
|
||||
184 185 186 187 188 189 190 191
|
||||
192 193 194 195 196 197 198 199
|
||||
200 201 202 203 204 205 206 207
|
||||
208 209 210 211 212 213 214 215
|
||||
216 217 218 219 220 221 222 223
|
||||
224 225 226 227 228 229 230 231
|
||||
232 233 234 235 236 237 238 239
|
||||
240 241 242 243 244 245 246 247
|
||||
248 249 250 251 252 253 254 255
|
||||
256>;
|
||||
};
|
||||
|
||||
clocks {
|
||||
compatible = "simple-bus";
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
clk32k_in: clock@0 {
|
||||
compatible = "fixed-clock";
|
||||
reg = <0>;
|
||||
#clock-cells = <0>;
|
||||
clock-frequency = <32768>;
|
||||
};
|
||||
};
|
||||
|
||||
gpio-keys {
|
||||
compatible = "gpio-keys";
|
||||
|
||||
lid {
|
||||
label = "Lid";
|
||||
gpios = <&gpio TEGRA_GPIO(R, 4) GPIO_ACTIVE_LOW>;
|
||||
linux,input-type = <5>;
|
||||
linux,code = <KEY_RESERVED>;
|
||||
debounce-interval = <1>;
|
||||
gpio-key,wakeup;
|
||||
};
|
||||
|
||||
power {
|
||||
label = "Power";
|
||||
gpios = <&gpio TEGRA_GPIO(Q, 0) GPIO_ACTIVE_LOW>;
|
||||
linux,code = <KEY_POWER>;
|
||||
debounce-interval = <30>;
|
||||
gpio-key,wakeup;
|
||||
};
|
||||
};
|
||||
|
||||
panel: panel {
|
||||
compatible = "auo,b133xtn01";
|
||||
|
||||
backlight = <&backlight>;
|
||||
};
|
||||
|
||||
sound {
|
||||
compatible = "nvidia,tegra-audio-max98090-nyan-big",
|
||||
"nvidia,tegra-audio-max98090";
|
||||
nvidia,model = "Acer Chromebook 13";
|
||||
|
||||
nvidia,audio-routing =
|
||||
"Headphones", "HPR",
|
||||
"Headphones", "HPL",
|
||||
"Speakers", "SPKR",
|
||||
"Speakers", "SPKL",
|
||||
"Mic Jack", "MICBIAS",
|
||||
"DMICL", "Int Mic",
|
||||
"DMICR", "Int Mic",
|
||||
"IN34", "Mic Jack";
|
||||
|
||||
nvidia,i2s-controller = <&tegra_i2s1>;
|
||||
nvidia,audio-codec = <&acodec>;
|
||||
|
||||
clocks = <&tegra_car TEGRA124_CLK_PLL_A>,
|
||||
<&tegra_car TEGRA124_CLK_PLL_A_OUT0>,
|
||||
<&tegra_car TEGRA124_CLK_EXTERN1>;
|
||||
clock-names = "pll_a", "pll_a_out0", "mclk";
|
||||
|
||||
nvidia,hp-det-gpios = <&gpio TEGRA_GPIO(I, 7) GPIO_ACTIVE_HIGH>;
|
||||
};
|
||||
};
|
||||
|
||||
#include "cros-ec-keyboard.dtsi"
|
|
@ -1,5 +1,6 @@
|
|||
#include <dt-bindings/clock/tegra124-car.h>
|
||||
#include <dt-bindings/gpio/tegra-gpio.h>
|
||||
#include <dt-bindings/pinctrl/pinctrl-tegra.h>
|
||||
#include <dt-bindings/interrupt-controller/arm-gic.h>
|
||||
|
||||
#include "skeleton.dtsi"
|
||||
|
@ -192,6 +193,16 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
pwm: pwm@7000a000 {
|
||||
compatible = "nvidia,tegra124-pwm", "nvidia,tegra20-pwm";
|
||||
reg = <0x7000a000 0x100>;
|
||||
#pwm-cells = <2>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_PWM>;
|
||||
resets = <&tegra_car 17>;
|
||||
reset-names = "pwm";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
spi@7000d400 {
|
||||
compatible = "nvidia,tegra124-spi", "nvidia,tegra114-spi";
|
||||
reg = <0x7000d400 0x200>;
|
||||
|
@ -290,6 +301,109 @@
|
|||
status = "disabled";
|
||||
};
|
||||
|
||||
ahub@70300000 {
|
||||
compatible = "nvidia,tegra124-ahub";
|
||||
reg = <0x70300000 0x200>,
|
||||
<0x70300800 0x800>,
|
||||
<0x70300200 0x600>;
|
||||
interrupts = <GIC_SPI 103 IRQ_TYPE_LEVEL_HIGH>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_D_AUDIO>,
|
||||
<&tegra_car TEGRA124_CLK_APBIF>;
|
||||
clock-names = "d_audio", "apbif";
|
||||
resets = <&tegra_car 106>, /* d_audio */
|
||||
<&tegra_car 107>, /* apbif */
|
||||
<&tegra_car 30>, /* i2s0 */
|
||||
<&tegra_car 11>, /* i2s1 */
|
||||
<&tegra_car 18>, /* i2s2 */
|
||||
<&tegra_car 101>, /* i2s3 */
|
||||
<&tegra_car 102>, /* i2s4 */
|
||||
<&tegra_car 108>, /* dam0 */
|
||||
<&tegra_car 109>, /* dam1 */
|
||||
<&tegra_car 110>, /* dam2 */
|
||||
<&tegra_car 10>, /* spdif */
|
||||
<&tegra_car 153>, /* amx */
|
||||
<&tegra_car 185>, /* amx1 */
|
||||
<&tegra_car 154>, /* adx */
|
||||
<&tegra_car 180>, /* adx1 */
|
||||
<&tegra_car 186>, /* afc0 */
|
||||
<&tegra_car 187>, /* afc1 */
|
||||
<&tegra_car 188>, /* afc2 */
|
||||
<&tegra_car 189>, /* afc3 */
|
||||
<&tegra_car 190>, /* afc4 */
|
||||
<&tegra_car 191>; /* afc5 */
|
||||
reset-names = "d_audio", "apbif", "i2s0", "i2s1", "i2s2",
|
||||
"i2s3", "i2s4", "dam0", "dam1", "dam2",
|
||||
"spdif", "amx", "amx1", "adx", "adx1",
|
||||
"afc0", "afc1", "afc2", "afc3", "afc4", "afc5";
|
||||
dmas = <&apbdma 1>, <&apbdma 1>,
|
||||
<&apbdma 2>, <&apbdma 2>,
|
||||
<&apbdma 3>, <&apbdma 3>,
|
||||
<&apbdma 4>, <&apbdma 4>,
|
||||
<&apbdma 6>, <&apbdma 6>,
|
||||
<&apbdma 7>, <&apbdma 7>,
|
||||
<&apbdma 12>, <&apbdma 12>,
|
||||
<&apbdma 13>, <&apbdma 13>,
|
||||
<&apbdma 14>, <&apbdma 14>,
|
||||
<&apbdma 29>, <&apbdma 29>;
|
||||
dma-names = "rx0", "tx0", "rx1", "tx1", "rx2", "tx2",
|
||||
"rx3", "tx3", "rx4", "tx4", "rx5", "tx5",
|
||||
"rx6", "tx6", "rx7", "tx7", "rx8", "tx8",
|
||||
"rx9", "tx9";
|
||||
ranges;
|
||||
#address-cells = <1>;
|
||||
#size-cells = <1>;
|
||||
|
||||
tegra_i2s0: i2s@70301000 {
|
||||
compatible = "nvidia,tegra124-i2s";
|
||||
reg = <0x70301000 0x100>;
|
||||
nvidia,ahub-cif-ids = <4 4>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_I2S0>;
|
||||
resets = <&tegra_car 30>;
|
||||
reset-names = "i2s";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tegra_i2s1: i2s@70301100 {
|
||||
compatible = "nvidia,tegra124-i2s";
|
||||
reg = <0x70301100 0x100>;
|
||||
nvidia,ahub-cif-ids = <5 5>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_I2S1>;
|
||||
resets = <&tegra_car 11>;
|
||||
reset-names = "i2s";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tegra_i2s2: i2s@70301200 {
|
||||
compatible = "nvidia,tegra124-i2s";
|
||||
reg = <0x70301200 0x100>;
|
||||
nvidia,ahub-cif-ids = <6 6>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_I2S2>;
|
||||
resets = <&tegra_car 18>;
|
||||
reset-names = "i2s";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tegra_i2s3: i2s@70301300 {
|
||||
compatible = "nvidia,tegra124-i2s";
|
||||
reg = <0x70301300 0x100>;
|
||||
nvidia,ahub-cif-ids = <7 7>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_I2S3>;
|
||||
resets = <&tegra_car 101>;
|
||||
reset-names = "i2s";
|
||||
status = "disabled";
|
||||
};
|
||||
|
||||
tegra_i2s4: i2s@70301400 {
|
||||
compatible = "nvidia,tegra124-i2s";
|
||||
reg = <0x70301400 0x100>;
|
||||
nvidia,ahub-cif-ids = <8 8>;
|
||||
clocks = <&tegra_car TEGRA124_CLK_I2S4>;
|
||||
resets = <&tegra_car 102>;
|
||||
reset-names = "i2s";
|
||||
status = "disabled";
|
||||
};
|
||||
};
|
||||
|
||||
usb@7d000000 {
|
||||
compatible = "nvidia,tegra124-ehci", "nvidia,tegra30-ehci";
|
||||
reg = <0x7d000000 0x4000>;
|
||||
|
|
|
@ -6,6 +6,10 @@
|
|||
model = "Avionic Design Tamonten™ NG Evaluation Carrier";
|
||||
compatible = "ad,tec-ng", "nvidia,tegra30";
|
||||
|
||||
aliases {
|
||||
i2c0 = "/i2c@7000c400";
|
||||
};
|
||||
|
||||
/* GEN2 */
|
||||
i2c@7000c400 {
|
||||
status = "okay";
|
||||
|
|
|
@ -167,6 +167,6 @@ struct i2c_ctlr {
|
|||
*
|
||||
* @return number of bus, or -1 if there is no DVC active
|
||||
*/
|
||||
int tegra_i2c_get_dvc_bus_num(void);
|
||||
int tegra_i2c_get_dvc_bus(struct udevice **busp);
|
||||
|
||||
#endif /* _TEGRA_I2C_H_ */
|
||||
|
|
|
@ -134,6 +134,23 @@
|
|||
num-gpios = <20>;
|
||||
};
|
||||
|
||||
i2c@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
compatible = "sandbox,i2c";
|
||||
clock-frequency = <400000>;
|
||||
eeprom@2c {
|
||||
reg = <0x2c>;
|
||||
compatible = "i2c-eeprom";
|
||||
emul {
|
||||
compatible = "sandbox,i2c-eeprom";
|
||||
sandbox,filename = "i2c.bin";
|
||||
sandbox,size = <128>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spi@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
26
arch/sandbox/include/asm/test.h
Normal file
26
arch/sandbox/include/asm/test.h
Normal file
|
@ -0,0 +1,26 @@
|
|||
/*
|
||||
* Test-related constants for sandbox
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __ASM_TEST_H
|
||||
#define __ASM_TEST_H
|
||||
|
||||
/* The sandbox driver always permits an I2C device with this address */
|
||||
#define SANDBOX_I2C_TEST_ADDR 0x59
|
||||
|
||||
enum sandbox_i2c_eeprom_test_mode {
|
||||
SIE_TEST_MODE_NONE,
|
||||
/* Permits read/write of only one byte per I2C transaction */
|
||||
SIE_TEST_MODE_SINGLE_BYTE,
|
||||
};
|
||||
|
||||
void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
|
||||
enum sandbox_i2c_eeprom_test_mode mode);
|
||||
|
||||
void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len);
|
||||
|
||||
#endif
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/gp_padctrl.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
|
@ -51,8 +52,15 @@ void gpio_early_init(void)
|
|||
|
||||
void pmu_write(uchar reg, uchar data)
|
||||
{
|
||||
i2c_set_bus_num(4); /* PMU is on bus 4 */
|
||||
i2c_write(PMU_I2C_ADDRESS, reg, 1, &data, 1);
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_chip_for_busnum(4, PMU_I2C_ADDRESS, &dev);
|
||||
if (ret) {
|
||||
debug("%s: Cannot find PMIC I2C chip\n", __func__);
|
||||
return;
|
||||
}
|
||||
i2c_write(dev, reg, &data, 1);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/gp_padctrl.h>
|
||||
#include "pinmux-config-cardhu.h"
|
||||
|
@ -37,17 +38,23 @@ void pinmux_init(void)
|
|||
*/
|
||||
void board_sdmmc_voltage_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
uchar reg, data_buffer[1];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
i2c_set_bus_num(0); /* PMU is on bus 0 */
|
||||
ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
|
||||
if (ret) {
|
||||
debug("%s: Cannot find PMIC I2C chip\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TPS659110: LDO5_REG = 3.3v, ACTIVE to SDMMC1 */
|
||||
data_buffer[0] = 0x65;
|
||||
reg = 0x32;
|
||||
|
||||
for (i = 0; i < MAX_I2C_RETRY; ++i) {
|
||||
if (i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1))
|
||||
if (i2c_write(dev, reg, data_buffer, 1))
|
||||
udelay(100);
|
||||
}
|
||||
|
||||
|
@ -56,7 +63,7 @@ void board_sdmmc_voltage_init(void)
|
|||
reg = 0x67;
|
||||
|
||||
for (i = 0; i < MAX_I2C_RETRY; ++i) {
|
||||
if (i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1))
|
||||
if (i2c_write(dev, reg, data_buffer, 1))
|
||||
udelay(100);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -113,10 +113,6 @@ int board_init(void)
|
|||
power_det_init();
|
||||
|
||||
#ifdef CONFIG_SYS_I2C_TEGRA
|
||||
#ifndef CONFIG_SYS_I2C_INIT_BOARD
|
||||
#error "You must define CONFIG_SYS_I2C_INIT_BOARD to use i2c on Nvidia boards"
|
||||
#endif
|
||||
i2c_init_board();
|
||||
# ifdef CONFIG_TEGRA_PMU
|
||||
if (pmu_set_nominal())
|
||||
debug("Failed to select nominal voltages\n");
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/arch/gp_padctrl.h>
|
||||
#include "pinmux-config-dalmore.h"
|
||||
|
@ -50,18 +51,21 @@ void pinmux_init(void)
|
|||
*/
|
||||
void board_sdmmc_voltage_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
uchar reg, data_buffer[1];
|
||||
int ret;
|
||||
|
||||
ret = i2c_set_bus_num(0);/* PMU is on bus 0 */
|
||||
if (ret)
|
||||
printf("%s: i2c_set_bus_num returned %d\n", __func__, ret);
|
||||
ret = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
|
||||
if (ret) {
|
||||
debug("%s: Cannot find PMIC I2C chip\n", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
/* TPS65913: LDO9_VOLTAGE = 3.3V */
|
||||
data_buffer[0] = 0x31;
|
||||
reg = 0x61;
|
||||
|
||||
ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
|
||||
ret = i2c_write(dev, reg, data_buffer, 1);
|
||||
if (ret)
|
||||
printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
|
||||
__func__, reg, data_buffer[0], ret);
|
||||
|
@ -70,7 +74,7 @@ void board_sdmmc_voltage_init(void)
|
|||
data_buffer[0] = 0x01;
|
||||
reg = 0x60;
|
||||
|
||||
ret = i2c_write(PMU_I2C_ADDRESS, reg, 1, data_buffer, 1);
|
||||
ret = i2c_write(dev, reg, data_buffer, 1);
|
||||
if (ret)
|
||||
printf("%s: PMU i2c_write %02X<-%02X returned %d\n",
|
||||
__func__, reg, data_buffer[0], ret);
|
||||
|
@ -79,7 +83,12 @@ void board_sdmmc_voltage_init(void)
|
|||
data_buffer[0] = 0x03;
|
||||
reg = 0x14;
|
||||
|
||||
ret = i2c_write(BAT_I2C_ADDRESS, reg, 1, data_buffer, 1);
|
||||
ret = i2c_get_chip_for_busnum(0, BAT_I2C_ADDRESS, &dev);
|
||||
if (ret) {
|
||||
debug("%s: Cannot find charger I2C chip\n", __func__);
|
||||
return;
|
||||
}
|
||||
ret = i2c_write(dev, reg, data_buffer, 1);
|
||||
if (ret)
|
||||
printf("%s: BAT i2c_write %02X<-%02X returned %d\n",
|
||||
__func__, reg, data_buffer[0], ret);
|
||||
|
|
24
board/nvidia/nyan-big/Kconfig
Normal file
24
board/nvidia/nyan-big/Kconfig
Normal file
|
@ -0,0 +1,24 @@
|
|||
if TARGET_NYAN_BIG
|
||||
|
||||
config SYS_CPU
|
||||
string
|
||||
default "arm720t" if SPL_BUILD
|
||||
default "armv7" if !SPL_BUILD
|
||||
|
||||
config SYS_BOARD
|
||||
string
|
||||
default "nyan-big"
|
||||
|
||||
config SYS_VENDOR
|
||||
string
|
||||
default "nvidia"
|
||||
|
||||
config SYS_SOC
|
||||
string
|
||||
default "tegra124"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
string
|
||||
default "nyan-big"
|
||||
|
||||
endif
|
6
board/nvidia/nyan-big/MAINTAINERS
Normal file
6
board/nvidia/nyan-big/MAINTAINERS
Normal file
|
@ -0,0 +1,6 @@
|
|||
NORRIN BOARD
|
||||
M: Allen Martin <amartin@nvidia.com>
|
||||
S: Maintained
|
||||
F: board/nvidia/nyan-big/
|
||||
F: include/configs/nyan-big.h
|
||||
F: configs/nyan-big_defconfig
|
9
board/nvidia/nyan-big/Makefile
Normal file
9
board/nvidia/nyan-big/Makefile
Normal file
|
@ -0,0 +1,9 @@
|
|||
#
|
||||
# (C) Copyright 2014
|
||||
# NVIDIA Corporation <www.nvidia.com>
|
||||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
|
||||
obj-y += ../venice2/as3722_init.o
|
||||
obj-y += nyan-big.o
|
27
board/nvidia/nyan-big/nyan-big.c
Normal file
27
board/nvidia/nyan-big/nyan-big.c
Normal file
|
@ -0,0 +1,27 @@
|
|||
/*
|
||||
* (C) Copyright 2014
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <asm/arch/gpio.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include "pinmux-config-nyan-big.h"
|
||||
|
||||
/*
|
||||
* Routine: pinmux_init
|
||||
* Description: Do individual peripheral pinmux configs
|
||||
*/
|
||||
void pinmux_init(void)
|
||||
{
|
||||
gpio_config_table(nyan_big_gpio_inits,
|
||||
ARRAY_SIZE(nyan_big_gpio_inits));
|
||||
|
||||
pinmux_config_pingrp_table(nyan_big_pingrps,
|
||||
ARRAY_SIZE(nyan_big_pingrps));
|
||||
|
||||
pinmux_config_drvgrp_table(nyan_big_drvgrps,
|
||||
ARRAY_SIZE(nyan_big_drvgrps));
|
||||
}
|
287
board/nvidia/nyan-big/pinmux-config-nyan-big.h
Normal file
287
board/nvidia/nyan-big/pinmux-config-nyan-big.h
Normal file
|
@ -0,0 +1,287 @@
|
|||
/*
|
||||
* Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef _PINMUX_CONFIG_NYAN_BIG_H_
|
||||
#define _PINMUX_CONFIG_NYAN_BIG_H_
|
||||
|
||||
#define GPIO_INIT(_gpio, _init) \
|
||||
{ \
|
||||
.gpio = GPIO_P##_gpio, \
|
||||
.init = TEGRA_GPIO_INIT_##_init, \
|
||||
}
|
||||
|
||||
static const struct tegra_gpio_config nyan_big_gpio_inits[] = {
|
||||
/* gpio, init_val */
|
||||
GPIO_INIT(A0, IN),
|
||||
GPIO_INIT(C7, IN),
|
||||
GPIO_INIT(G0, IN),
|
||||
GPIO_INIT(G1, IN),
|
||||
GPIO_INIT(G2, IN),
|
||||
GPIO_INIT(G3, IN),
|
||||
GPIO_INIT(H2, IN),
|
||||
GPIO_INIT(H4, IN),
|
||||
GPIO_INIT(H6, IN),
|
||||
GPIO_INIT(H7, OUT1),
|
||||
GPIO_INIT(I0, IN),
|
||||
GPIO_INIT(I1, IN),
|
||||
GPIO_INIT(I5, OUT1),
|
||||
GPIO_INIT(I6, IN),
|
||||
GPIO_INIT(I7, IN),
|
||||
GPIO_INIT(J0, IN),
|
||||
GPIO_INIT(J7, IN),
|
||||
GPIO_INIT(K1, OUT0),
|
||||
GPIO_INIT(K2, IN),
|
||||
GPIO_INIT(K4, OUT0),
|
||||
GPIO_INIT(K6, OUT0),
|
||||
GPIO_INIT(K7, IN),
|
||||
GPIO_INIT(N7, IN),
|
||||
GPIO_INIT(P2, OUT0),
|
||||
GPIO_INIT(Q0, IN),
|
||||
GPIO_INIT(Q2, IN),
|
||||
GPIO_INIT(Q3, IN),
|
||||
GPIO_INIT(Q6, IN),
|
||||
GPIO_INIT(Q7, IN),
|
||||
GPIO_INIT(R0, OUT0),
|
||||
GPIO_INIT(R1, IN),
|
||||
GPIO_INIT(R4, IN),
|
||||
GPIO_INIT(R7, IN),
|
||||
GPIO_INIT(S3, OUT0),
|
||||
GPIO_INIT(S4, OUT0),
|
||||
GPIO_INIT(S7, IN),
|
||||
GPIO_INIT(T1, IN),
|
||||
GPIO_INIT(U4, IN),
|
||||
GPIO_INIT(U5, IN),
|
||||
GPIO_INIT(U6, IN),
|
||||
GPIO_INIT(V0, IN),
|
||||
GPIO_INIT(W3, IN),
|
||||
GPIO_INIT(X1, IN),
|
||||
GPIO_INIT(X4, IN),
|
||||
GPIO_INIT(X7, OUT0),
|
||||
};
|
||||
|
||||
#define PINCFG(_pingrp, _mux, _pull, _tri, _io, _od, _rcv_sel) \
|
||||
{ \
|
||||
.pingrp = PMUX_PINGRP_##_pingrp, \
|
||||
.func = PMUX_FUNC_##_mux, \
|
||||
.pull = PMUX_PULL_##_pull, \
|
||||
.tristate = PMUX_TRI_##_tri, \
|
||||
.io = PMUX_PIN_##_io, \
|
||||
.od = PMUX_PIN_OD_##_od, \
|
||||
.rcv_sel = PMUX_PIN_RCV_SEL_##_rcv_sel, \
|
||||
.lock = PMUX_PIN_LOCK_DEFAULT, \
|
||||
.ioreset = PMUX_PIN_IO_RESET_DEFAULT, \
|
||||
}
|
||||
|
||||
static const struct pmux_pingrp_config nyan_big_pingrps[] = {
|
||||
/* pingrp, mux, pull, tri, e_input, od, rcv_sel */
|
||||
PINCFG(CLK_32K_OUT_PA0, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART3_CTS_N_PA1, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP2_FS_PA2, I2S1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP2_SCLK_PA3, I2S1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP2_DIN_PA4, I2S1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP2_DOUT_PA5, I2S1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_CLK_PA6, SDMMC3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_CMD_PA7, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PB0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PB1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_DAT3_PB4, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_DAT2_PB5, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_DAT1_PB6, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_DAT0_PB7, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART3_RTS_N_PC0, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART2_TXD_PC2, IRDA, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART2_RXD_PC3, IRDA, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GEN1_I2C_SCL_PC4, I2C1, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(GEN1_I2C_SDA_PC5, I2C1, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(PC7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG0, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG1, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG2, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG3, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG4, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG5, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG6, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PG7, SPI4, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH0, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH1, PWM1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH2, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH3, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH4, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH6, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PH7, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI0, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI1, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI2, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI3, SPI4, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI4, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI5, DEFAULT, UP, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI6, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PI7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PJ0, DEFAULT, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PJ2, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART2_CTS_N_PJ5, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART2_RTS_N_PJ6, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PJ7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PK0, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PK1, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PK2, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PK3, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PK4, DEFAULT, UP, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SPDIF_OUT_PK5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SPDIF_IN_PK6, DEFAULT, DOWN, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PK7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP1_FS_PN0, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP1_DIN_PN1, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP1_DOUT_PN2, I2S0, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP1_SCLK_PN3, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(USB_VBUS_EN0_PN4, USB, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(USB_VBUS_EN1_PN5, USB, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(HDMI_INT_PN7, DEFAULT, DOWN, NORMAL, INPUT, DEFAULT, NORMAL),
|
||||
PINCFG(ULPI_DATA7_PO0, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA0_PO1, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA1_PO2, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA2_PO3, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA3_PO4, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA4_PO5, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA5_PO6, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DATA6_PO7, ULPI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP3_FS_PP0, I2S2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP3_DIN_PP1, I2S2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP3_DOUT_PP2, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP3_SCLK_PP3, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP4_FS_PP4, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP4_DIN_PP5, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP4_DOUT_PP6, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP4_SCLK_PP7, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL0_PQ0, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL1_PQ1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL2_PQ2, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL3_PQ3, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL4_PQ4, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL5_PQ5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL6_PQ6, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_COL7_PQ7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW0_PR0, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW1_PR1, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW2_PR2, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW3_PR3, KBC, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW4_PR4, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW5_PR5, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW6_PR6, KBC, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW7_PR7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW8_PS0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW9_PS1, UARTA, DOWN, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW10_PS2, UARTA, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW11_PS3, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW12_PS4, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW13_PS5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW14_PS6, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW15_PS7, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW16_PT0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(KB_ROW17_PT1, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GEN2_I2C_SCL_PT5, I2C2, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(GEN2_I2C_SDA_PT6, I2C2, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(SDMMC4_CMD_PT7, SDMMC4, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU0, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU1, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU2, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU3, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU4, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU5, DEFAULT, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PU6, DEFAULT, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PV0, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PV1, RSVD1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_CD_N_PV2, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_WP_N_PV3, SDMMC1, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DDC_SCL_PV4, I2C4, NORMAL, NORMAL, INPUT, DEFAULT, NORMAL),
|
||||
PINCFG(DDC_SDA_PV5, I2C4, NORMAL, NORMAL, INPUT, DEFAULT, NORMAL),
|
||||
PINCFG(GPIO_W2_AUD_PW2, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_W3_AUD_PW3, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP_MCLK1_PW4, EXTPERIPH1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CLK2_OUT_PW5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART3_TXD_PW6, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(UART3_RXD_PW7, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DVFS_PWM_PX0, CLDVFS, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_X1_AUD_PX1, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DVFS_CLK_PX2, CLDVFS, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_X3_AUD_PX3, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_X4_AUD_PX4, DEFAULT, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_X5_AUD_PX5, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_X6_AUD_PX6, GMI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(GPIO_X7_AUD_PX7, DEFAULT, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_CLK_PY0, SPI1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_DIR_PY1, SPI1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_NXT_PY2, SPI1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(ULPI_STP_PY3, SPI1, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_DAT3_PY4, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_DAT2_PY5, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_DAT1_PY6, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_DAT0_PY7, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_CLK_PZ0, SDMMC1, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC1_CMD_PZ1, SDMMC1, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PWR_I2C_SCL_PZ6, I2CPWR, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(PWR_I2C_SDA_PZ7, I2CPWR, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT0_PAA0, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT1_PAA1, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT2_PAA2, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT3_PAA3, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT4_PAA4, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT5_PAA5, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT6_PAA6, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_DAT7_PAA7, SDMMC4, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PBB0, VGP6, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CAM_I2C_SCL_PBB1, RSVD3, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
|
||||
PINCFG(CAM_I2C_SDA_PBB2, RSVD3, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
|
||||
PINCFG(PBB3, VGP3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PBB4, VGP4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PBB5, RSVD3, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PBB6, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PBB7, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CAM_MCLK_PCC0, VI, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PCC1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PCC2, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC4_CLK_PCC4, SDMMC4, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CLK2_REQ_PCC5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PEX_L0_RST_N_PDD1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PEX_L0_CLKREQ_N_PDD2, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PEX_WAKE_N_PDD3, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PEX_L1_RST_N_PDD5, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PEX_L1_CLKREQ_N_PDD6, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CLK3_OUT_PEE0, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CLK3_REQ_PEE1, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DAP_MCLK1_REQ_PEE2, RSVD4, DOWN, TRISTATE, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(HDMI_CEC_PEE3, CEC, NORMAL, NORMAL, INPUT, ENABLE, DEFAULT),
|
||||
PINCFG(SDMMC3_CLK_LB_OUT_PEE4, SDMMC3, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(SDMMC3_CLK_LB_IN_PEE5, SDMMC3, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(DP_HPD_PFF0, DP, UP, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(USB_VBUS_EN2_PFF1, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
|
||||
PINCFG(PFF2, RSVD2, DOWN, TRISTATE, OUTPUT, DISABLE, DEFAULT),
|
||||
PINCFG(CORE_PWR_REQ, PWRON, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(CPU_PWR_REQ, CPU, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(PWR_INT_N, PMI, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(RESET_OUT_N, RESET_OUT_N, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(OWR, RSVD2, DOWN, TRISTATE, OUTPUT, DEFAULT, NORMAL),
|
||||
PINCFG(CLK_32K_IN, CLK, NORMAL, NORMAL, INPUT, DEFAULT, DEFAULT),
|
||||
PINCFG(JTAG_RTCK, RTCK, NORMAL, NORMAL, OUTPUT, DEFAULT, DEFAULT),
|
||||
};
|
||||
|
||||
#define DRVCFG(_drvgrp, _slwf, _slwr, _drvup, _drvdn, _lpmd, _schmt, _hsm) \
|
||||
{ \
|
||||
.drvgrp = PMUX_DRVGRP_##_drvgrp, \
|
||||
.slwf = _slwf, \
|
||||
.slwr = _slwr, \
|
||||
.drvup = _drvup, \
|
||||
.drvdn = _drvdn, \
|
||||
.lpmd = PMUX_LPMD_##_lpmd, \
|
||||
.schmt = PMUX_SCHMT_##_schmt, \
|
||||
.hsm = PMUX_HSM_##_hsm, \
|
||||
}
|
||||
|
||||
static const struct pmux_drvgrp_config nyan_big_drvgrps[] = {
|
||||
};
|
||||
|
||||
#endif /* PINMUX_CONFIG_NYAN_BIG_H */
|
|
@ -18,7 +18,7 @@
|
|||
#define AS3722_LDO6VOLTAGE_REG 0x16 /* VDD_SDMMC */
|
||||
#define AS3722_LDCONTROL_REG 0x4E
|
||||
|
||||
#ifdef CONFIG_TARGET_JETSON_TK1
|
||||
#if defined(CONFIG_TARGET_JETSON_TK1) || defined(CONFIG_TARGET_NYAN_BIG)
|
||||
#define AS3722_SD0VOLTAGE_DATA (0x3C00 | AS3722_SD0VOLTAGE_REG)
|
||||
#else
|
||||
#define AS3722_SD0VOLTAGE_DATA (0x2800 | AS3722_SD0VOLTAGE_REG)
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/tegra.h>
|
||||
#include <asm/arch/clock.h>
|
||||
|
@ -21,23 +22,26 @@
|
|||
*/
|
||||
void pin_mux_mmc(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
uchar val;
|
||||
int ret;
|
||||
|
||||
/* Turn on MAX8907B LDO12 to 2.8V for J40 power */
|
||||
ret = i2c_set_bus_num(0);
|
||||
if (ret)
|
||||
printf("i2c_set_bus_num failed: %d\n", ret);
|
||||
ret = i2c_get_chip_for_busnum(0, 0x3c, &dev);
|
||||
if (ret) {
|
||||
printf("%s: Cannot find MAX8907B I2C chip\n", __func__);
|
||||
return;
|
||||
}
|
||||
val = 0x29;
|
||||
ret = i2c_write(0x3c, 0x46, 1, &val, 1);
|
||||
ret = i2c_write(dev, 0x46, &val, 1);
|
||||
if (ret)
|
||||
printf("i2c_write 0 0x3c 0x46 failed: %d\n", ret);
|
||||
val = 0x00;
|
||||
ret = i2c_write(0x3c, 0x45, 1, &val, 1);
|
||||
ret = i2c_write(dev, 0x45, &val, 1);
|
||||
if (ret)
|
||||
printf("i2c_write 0 0x3c 0x45 failed: %d\n", ret);
|
||||
val = 0x1f;
|
||||
ret = i2c_write(0x3c, 0x44, 1, &val, 1);
|
||||
ret = i2c_write(dev, 0x44, &val, 1);
|
||||
if (ret)
|
||||
printf("i2c_write 0 0x3c 0x44 failed: %d\n", ret);
|
||||
|
||||
|
@ -49,6 +53,7 @@ void pin_mux_mmc(void)
|
|||
/* this is a weak define that we are overriding */
|
||||
void pin_mux_usb(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
uchar val;
|
||||
int ret;
|
||||
|
||||
|
@ -59,15 +64,17 @@ void pin_mux_usb(void)
|
|||
*/
|
||||
|
||||
/* Turn on TAC6416's GPIO 0+1 for USB1/3's VBUS */
|
||||
ret = i2c_set_bus_num(0);
|
||||
if (ret)
|
||||
printf("i2c_set_bus_num failed: %d\n", ret);
|
||||
ret = i2c_get_chip_for_busnum(0, 0x20, &dev);
|
||||
if (ret) {
|
||||
printf("%s: Cannot find TAC6416 I2C chip\n", __func__);
|
||||
return;
|
||||
}
|
||||
val = 0x03;
|
||||
ret = i2c_write(0x20, 2, 1, &val, 1);
|
||||
ret = i2c_write(dev, 2, &val, 1);
|
||||
if (ret)
|
||||
printf("i2c_write 0 0x20 2 failed: %d\n", ret);
|
||||
val = 0xfc;
|
||||
ret = i2c_write(0x20, 6, 1, &val, 1);
|
||||
ret = i2c_write(dev, 6, &val, 1);
|
||||
if (ret)
|
||||
printf("i2c_write 0 0x20 6 failed: %d\n", ret);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include <asm/arch/mbox.h>
|
||||
#include <asm/arch/sdhci.h>
|
||||
#include <asm/global_data.h>
|
||||
#include <dm/platform_data/serial_pl01x.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -36,6 +37,17 @@ U_BOOT_DEVICE(bcm2835_gpios) = {
|
|||
.platdata = &gpio_platdata,
|
||||
};
|
||||
|
||||
static const struct pl01x_serial_platdata serial_platdata = {
|
||||
.base = 0x20201000,
|
||||
.type = TYPE_PL011,
|
||||
.clock = 3000000,
|
||||
};
|
||||
|
||||
U_BOOT_DEVICE(bcm2835_serials) = {
|
||||
.name = "serial_pl01x",
|
||||
.platdata = &serial_platdata,
|
||||
};
|
||||
|
||||
struct msg_get_arm_mem {
|
||||
struct bcm2835_mbox_hdr hdr;
|
||||
struct bcm2835_mbox_tag_get_arm_mem get_arm_mem;
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
|
||||
#include <dm.h>
|
||||
#include <asm/arch/gp_padctrl.h>
|
||||
#include <asm/arch/pinmux.h>
|
||||
#include <asm/gpio.h>
|
||||
|
@ -38,23 +38,20 @@ void pinmux_init(void)
|
|||
#ifdef CONFIG_PCI_TEGRA
|
||||
int tegra_pcie_board_init(void)
|
||||
{
|
||||
unsigned int old_bus;
|
||||
struct udevice *dev;
|
||||
u8 addr, data[1];
|
||||
int err;
|
||||
|
||||
old_bus = i2c_get_bus_num();
|
||||
|
||||
err = i2c_set_bus_num(0);
|
||||
err = i2c_get_chip_for_busnum(0, PMU_I2C_ADDRESS, &dev);
|
||||
if (err) {
|
||||
debug("failed to set I2C bus\n");
|
||||
debug("%s: Cannot find PMIC I2C chip\n", __func__);
|
||||
return err;
|
||||
}
|
||||
|
||||
/* TPS659110: VDD2_OP_REG = 1.05V */
|
||||
data[0] = 0x27;
|
||||
addr = 0x25;
|
||||
|
||||
err = i2c_write(PMU_I2C_ADDRESS, addr, 1, data, 1);
|
||||
err = i2c_write(dev, addr, data, 1);
|
||||
if (err) {
|
||||
debug("failed to set VDD supply\n");
|
||||
return err;
|
||||
|
@ -64,7 +61,7 @@ int tegra_pcie_board_init(void)
|
|||
data[0] = 0x0D;
|
||||
addr = 0x24;
|
||||
|
||||
err = i2c_write(PMU_I2C_ADDRESS, addr, 1, data, 1);
|
||||
err = i2c_write(dev, addr, data, 1);
|
||||
if (err) {
|
||||
debug("failed to enable VDD supply\n");
|
||||
return err;
|
||||
|
@ -74,14 +71,12 @@ int tegra_pcie_board_init(void)
|
|||
data[0] = 0x0D;
|
||||
addr = 0x35;
|
||||
|
||||
err = i2c_write(PMU_I2C_ADDRESS, addr, 1, data, 1);
|
||||
err = i2c_write(dev, addr, data, 1);
|
||||
if (err) {
|
||||
debug("failed to set AVDD supply\n");
|
||||
return err;
|
||||
}
|
||||
|
||||
i2c_set_bus_num(old_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
374
common/cmd_i2c.c
374
common/cmd_i2c.c
|
@ -69,8 +69,10 @@
|
|||
#include <bootretry.h>
|
||||
#include <cli.h>
|
||||
#include <command.h>
|
||||
#include <dm.h>
|
||||
#include <edid.h>
|
||||
#include <environment.h>
|
||||
#include <errno.h>
|
||||
#include <i2c.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/byteorder.h>
|
||||
|
@ -117,6 +119,60 @@ static uchar i2c_no_probes[] = CONFIG_SYS_I2C_NOPROBES;
|
|||
|
||||
#define DISP_LINE_LEN 16
|
||||
|
||||
/*
|
||||
* Default for driver model is to use the chip's existing address length.
|
||||
* For legacy code, this is not stored, so we need to use a suitable
|
||||
* default.
|
||||
*/
|
||||
#ifdef CONFIG_DM_I2C
|
||||
#define DEFAULT_ADDR_LEN (-1)
|
||||
#else
|
||||
#define DEFAULT_ADDR_LEN 1
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
static struct udevice *i2c_cur_bus;
|
||||
|
||||
static int i2c_set_bus_num(unsigned int busnum)
|
||||
{
|
||||
struct udevice *bus;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
|
||||
if (ret) {
|
||||
debug("%s: No bus %d\n", __func__, busnum);
|
||||
return ret;
|
||||
}
|
||||
i2c_cur_bus = bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_get_cur_bus(struct udevice **busp)
|
||||
{
|
||||
if (!i2c_cur_bus) {
|
||||
puts("No I2C bus selected\n");
|
||||
return -ENODEV;
|
||||
}
|
||||
*busp = i2c_cur_bus;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_get_cur_bus_chip(uint chip_addr, struct udevice **devp)
|
||||
{
|
||||
struct udevice *bus;
|
||||
int ret;
|
||||
|
||||
ret = i2c_get_cur_bus(&bus);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
return i2c_get_chip(bus, chip_addr, devp);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/**
|
||||
* i2c_init_board() - Board-specific I2C bus init
|
||||
*
|
||||
|
@ -143,7 +199,7 @@ void i2c_init_board(void)
|
|||
*
|
||||
* Returns I2C bus speed in Hz.
|
||||
*/
|
||||
#if !defined(CONFIG_SYS_I2C)
|
||||
#if !defined(CONFIG_SYS_I2C) && !defined(CONFIG_DM_I2C)
|
||||
/*
|
||||
* TODO: Implement architecture-specific get/set functions
|
||||
* Should go away, if we switched completely to new multibus support
|
||||
|
@ -182,12 +238,12 @@ int i2c_set_bus_speed(unsigned int speed)
|
|||
*
|
||||
* Returns the address length.
|
||||
*/
|
||||
static uint get_alen(char *arg)
|
||||
static uint get_alen(char *arg, int default_len)
|
||||
{
|
||||
int j;
|
||||
int alen;
|
||||
|
||||
alen = 1;
|
||||
alen = default_len;
|
||||
for (j = 0; j < 8; j++) {
|
||||
if (arg[j] == '.') {
|
||||
alen = arg[j+1] - '0';
|
||||
|
@ -227,8 +283,13 @@ static int i2c_report_err(int ret, enum i2c_err_op op)
|
|||
static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
u_char chip;
|
||||
uint devaddr, alen, length;
|
||||
uint devaddr, length;
|
||||
int alen;
|
||||
u_char *memaddr;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if (argc != 5)
|
||||
return CMD_RET_USAGE;
|
||||
|
@ -243,7 +304,7 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||
* 2 bytes long. Some day it might be 3 bytes long :-).
|
||||
*/
|
||||
devaddr = simple_strtoul(argv[2], NULL, 16);
|
||||
alen = get_alen(argv[2]);
|
||||
alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
|
@ -257,18 +318,31 @@ static int do_i2c_read ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||
*/
|
||||
memaddr = (u_char *)simple_strtoul(argv[4], NULL, 16);
|
||||
|
||||
if (i2c_read(chip, devaddr, alen, memaddr, length) != 0) {
|
||||
i2c_report_err(-1, I2C_ERR_READ);
|
||||
return 1;
|
||||
}
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (!ret)
|
||||
ret = i2c_read(dev, devaddr, memaddr, length);
|
||||
#else
|
||||
ret = i2c_read(chip, devaddr, alen, memaddr, length);
|
||||
#endif
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_READ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
u_char chip;
|
||||
uint devaddr, alen, length;
|
||||
uint devaddr, length;
|
||||
int alen;
|
||||
u_char *memaddr;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if (argc != 5)
|
||||
return cmd_usage(cmdtp);
|
||||
|
@ -288,7 +362,7 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
|
|||
* 2 bytes long. Some day it might be 3 bytes long :-).
|
||||
*/
|
||||
devaddr = simple_strtoul(argv[3], NULL, 16);
|
||||
alen = get_alen(argv[3]);
|
||||
alen = get_alen(argv[3], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return cmd_usage(cmdtp);
|
||||
|
||||
|
@ -297,10 +371,22 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
|
|||
*/
|
||||
length = simple_strtoul(argv[4], NULL, 16);
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
#endif
|
||||
|
||||
while (length-- > 0) {
|
||||
if (i2c_write(chip, devaddr++, alen, memaddr++, 1) != 0) {
|
||||
return i2c_report_err(-1, I2C_ERR_WRITE);
|
||||
}
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_write(dev, devaddr++, memaddr++, 1);
|
||||
#else
|
||||
ret = i2c_write(chip, devaddr++, alen, memaddr++, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
/*
|
||||
* No write delay with FRAM devices.
|
||||
*/
|
||||
|
@ -311,6 +397,38 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
static int do_i2c_flags(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char *const argv[])
|
||||
{
|
||||
struct udevice *dev;
|
||||
uint flags;
|
||||
int chip;
|
||||
int ret;
|
||||
|
||||
if (argc < 2)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
chip = simple_strtoul(argv[1], NULL, 16);
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_READ);
|
||||
|
||||
if (argc > 2) {
|
||||
flags = simple_strtoul(argv[2], NULL, 16);
|
||||
ret = i2c_set_chip_flags(dev, flags);
|
||||
} else {
|
||||
ret = i2c_get_chip_flags(dev, &flags);
|
||||
if (!ret)
|
||||
printf("%x\n", flags);
|
||||
}
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_READ);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* do_i2c_md() - Handle the "i2c md" command-line command
|
||||
* @cmdtp: Command data struct pointer
|
||||
|
@ -327,8 +445,13 @@ static int do_i2c_write(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[
|
|||
static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
u_char chip;
|
||||
uint addr, alen, length;
|
||||
uint addr, length;
|
||||
int alen;
|
||||
int j, nbytes, linebytes;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
/* We use the last specified parameters, unless new ones are
|
||||
* entered.
|
||||
|
@ -356,7 +479,7 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
* 2 bytes long. Some day it might be 3 bytes long :-).
|
||||
*/
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
alen = get_alen(argv[2]);
|
||||
alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
|
@ -368,6 +491,14 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
length = simple_strtoul(argv[3], NULL, 16);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_READ);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print the lines.
|
||||
*
|
||||
|
@ -381,8 +512,13 @@ static int do_i2c_md ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
|
||||
linebytes = (nbytes > DISP_LINE_LEN) ? DISP_LINE_LEN : nbytes;
|
||||
|
||||
if (i2c_read(chip, addr, alen, linebuf, linebytes) != 0)
|
||||
i2c_report_err(-1, I2C_ERR_READ);
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_read(dev, addr, linebuf, linebytes);
|
||||
#else
|
||||
ret = i2c_read(chip, addr, alen, linebuf, linebytes);
|
||||
#endif
|
||||
if (ret)
|
||||
i2c_report_err(ret, I2C_ERR_READ);
|
||||
else {
|
||||
printf("%04x:", addr);
|
||||
cp = linebuf;
|
||||
|
@ -429,9 +565,13 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
{
|
||||
uchar chip;
|
||||
ulong addr;
|
||||
uint alen;
|
||||
int alen;
|
||||
uchar byte;
|
||||
int count;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if ((argc < 4) || (argc > 5))
|
||||
return CMD_RET_USAGE;
|
||||
|
@ -445,10 +585,17 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
* Address is always specified.
|
||||
*/
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
alen = get_alen(argv[2]);
|
||||
alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
#endif
|
||||
/*
|
||||
* Value to write is always specified.
|
||||
*/
|
||||
|
@ -463,8 +610,13 @@ static int do_i2c_mw ( cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
count = 1;
|
||||
|
||||
while (count-- > 0) {
|
||||
if (i2c_write(chip, addr++, alen, &byte, 1) != 0)
|
||||
i2c_report_err(-1, I2C_ERR_WRITE);
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_write(dev, addr++, &byte, 1);
|
||||
#else
|
||||
ret = i2c_write(chip, addr++, alen, &byte, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
/*
|
||||
* Wait for the write to complete. The write can take
|
||||
* up to 10mSec (we allow a little more time).
|
||||
|
@ -499,11 +651,15 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
{
|
||||
uchar chip;
|
||||
ulong addr;
|
||||
uint alen;
|
||||
int alen;
|
||||
int count;
|
||||
uchar byte;
|
||||
ulong crc;
|
||||
ulong err;
|
||||
int ret = 0;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if (argc < 4)
|
||||
return CMD_RET_USAGE;
|
||||
|
@ -517,10 +673,17 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
* Address is always specified.
|
||||
*/
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
alen = get_alen(argv[2]);
|
||||
alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_READ);
|
||||
#endif
|
||||
/*
|
||||
* Count is always specified
|
||||
*/
|
||||
|
@ -534,13 +697,18 @@ static int do_i2c_crc (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
crc = 0;
|
||||
err = 0;
|
||||
while (count-- > 0) {
|
||||
if (i2c_read(chip, addr, alen, &byte, 1) != 0)
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_read(dev, addr, &byte, 1);
|
||||
#else
|
||||
ret = i2c_read(chip, addr, alen, &byte, 1);
|
||||
#endif
|
||||
if (ret)
|
||||
err++;
|
||||
crc = crc32 (crc, &byte, 1);
|
||||
addr++;
|
||||
}
|
||||
if (err > 0)
|
||||
i2c_report_err(-1, I2C_ERR_READ);
|
||||
i2c_report_err(ret, I2C_ERR_READ);
|
||||
else
|
||||
printf ("%08lx\n", crc);
|
||||
|
||||
|
@ -568,10 +736,14 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
|
|||
{
|
||||
uchar chip;
|
||||
ulong addr;
|
||||
uint alen;
|
||||
int alen;
|
||||
ulong data;
|
||||
int size = 1;
|
||||
int nbytes;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if (argc != 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
@ -601,19 +773,32 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
|
|||
* Address is always specified.
|
||||
*/
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
alen = get_alen(argv[2]);
|
||||
alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return CMD_RET_USAGE;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Print the address, followed by value. Then accept input for
|
||||
* the next value. A non-converted value exits.
|
||||
*/
|
||||
do {
|
||||
printf("%08lx:", addr);
|
||||
if (i2c_read(chip, addr, alen, (uchar *)&data, size) != 0)
|
||||
i2c_report_err(-1, I2C_ERR_READ);
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_read(dev, addr, (uchar *)&data, size);
|
||||
#else
|
||||
ret = i2c_read(chip, addr, alen, (uchar *)&data, size);
|
||||
#endif
|
||||
if (ret)
|
||||
i2c_report_err(ret, I2C_ERR_READ);
|
||||
else {
|
||||
data = cpu_to_be32(data);
|
||||
if (size == 1)
|
||||
|
@ -655,8 +840,15 @@ mod_i2c_mem(cmd_tbl_t *cmdtp, int incrflag, int flag, int argc, char * const arg
|
|||
* good enough to not time out
|
||||
*/
|
||||
bootretry_reset_cmd_timeout();
|
||||
if (i2c_write(chip, addr, alen, (uchar *)&data, size) != 0)
|
||||
i2c_report_err(-1, I2C_ERR_WRITE);
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_write(dev, addr, (uchar *)&data,
|
||||
size);
|
||||
#else
|
||||
ret = i2c_write(chip, addr, alen,
|
||||
(uchar *)&data, size);
|
||||
#endif
|
||||
if (ret)
|
||||
i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
#ifdef CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS
|
||||
udelay(CONFIG_SYS_EEPROM_PAGE_WRITE_DELAY_MS * 1000);
|
||||
#endif
|
||||
|
@ -697,6 +889,13 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||
int k, skip;
|
||||
unsigned int bus = GET_BUS_NUM;
|
||||
#endif /* NOPROBES */
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *bus, *dev;
|
||||
|
||||
if (i2c_get_cur_bus(&bus))
|
||||
return CMD_RET_FAILURE;
|
||||
#endif
|
||||
|
||||
if (argc == 2)
|
||||
addr = simple_strtol(argv[1], 0, 16);
|
||||
|
@ -717,7 +916,12 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||
if (skip)
|
||||
continue;
|
||||
#endif
|
||||
if (i2c_probe(j) == 0) {
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_probe(bus, j, 0, &dev);
|
||||
#else
|
||||
ret = i2c_probe(j);
|
||||
#endif
|
||||
if (ret == 0) {
|
||||
printf(" %02X", j);
|
||||
found++;
|
||||
}
|
||||
|
@ -754,11 +958,15 @@ static int do_i2c_probe (cmd_tbl_t *cmdtp, int flag, int argc, char * const argv
|
|||
static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
u_char chip;
|
||||
ulong alen;
|
||||
int alen;
|
||||
uint addr;
|
||||
uint length;
|
||||
u_char bytes[16];
|
||||
int delay;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if (argc < 3)
|
||||
return CMD_RET_USAGE;
|
||||
|
@ -772,9 +980,16 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
* Address is always specified.
|
||||
*/
|
||||
addr = simple_strtoul(argv[2], NULL, 16);
|
||||
alen = get_alen(argv[2]);
|
||||
alen = get_alen(argv[2], DEFAULT_ADDR_LEN);
|
||||
if (alen > 3)
|
||||
return CMD_RET_USAGE;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret && alen != -1)
|
||||
ret = i2c_set_chip_offset_len(dev, alen);
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_WRITE);
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Length is the number of objects, not number of bytes.
|
||||
|
@ -794,8 +1009,13 @@ static int do_i2c_loop(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]
|
|||
* Run the loop...
|
||||
*/
|
||||
while (1) {
|
||||
if (i2c_read(chip, addr, alen, bytes, length) != 0)
|
||||
i2c_report_err(-1, I2C_ERR_READ);
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_read(dev, addr, bytes, length);
|
||||
#else
|
||||
ret = i2c_read(chip, addr, alen, bytes, length);
|
||||
#endif
|
||||
if (ret)
|
||||
i2c_report_err(ret, I2C_ERR_READ);
|
||||
udelay(delay);
|
||||
}
|
||||
|
||||
|
@ -1345,6 +1565,10 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||
{
|
||||
u_char chip;
|
||||
struct edid1_info edid;
|
||||
int ret;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *dev;
|
||||
#endif
|
||||
|
||||
if (argc < 2) {
|
||||
cmd_usage(cmdtp);
|
||||
|
@ -1352,10 +1576,15 @@ int do_edid(cmd_tbl_t *cmdtp, int flag, int argc, char *const argv[])
|
|||
}
|
||||
|
||||
chip = simple_strtoul(argv[1], NULL, 16);
|
||||
if (i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid)) != 0) {
|
||||
i2c_report_err(-1, I2C_ERR_READ);
|
||||
return 1;
|
||||
}
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_cur_bus_chip(chip, &dev);
|
||||
if (!ret)
|
||||
ret = i2c_read(dev, 0, (uchar *)&edid, sizeof(edid));
|
||||
#else
|
||||
ret = i2c_read(chip, 0, 1, (uchar *)&edid, sizeof(edid));
|
||||
#endif
|
||||
if (ret)
|
||||
return i2c_report_err(ret, I2C_ERR_READ);
|
||||
|
||||
if (edid_check_info(&edid)) {
|
||||
puts("Content isn't valid EDID.\n");
|
||||
|
@ -1437,17 +1666,28 @@ static int do_i2c_show_bus(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
* Returns zero on success, CMD_RET_USAGE in case of misuse and negative
|
||||
* on error.
|
||||
*/
|
||||
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS)
|
||||
#if defined(CONFIG_SYS_I2C) || defined(CONFIG_I2C_MULTI_BUS) || \
|
||||
defined(CONFIG_DM_I2C)
|
||||
static int do_i2c_bus_num(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
char * const argv[])
|
||||
{
|
||||
int ret = 0;
|
||||
unsigned int bus_no;
|
||||
int bus_no;
|
||||
|
||||
if (argc == 1)
|
||||
if (argc == 1) {
|
||||
/* querying current setting */
|
||||
printf("Current bus is %d\n", i2c_get_bus_num());
|
||||
else {
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *bus;
|
||||
|
||||
if (!i2c_get_cur_bus(&bus))
|
||||
bus_no = bus->seq;
|
||||
else
|
||||
bus_no = -1;
|
||||
#else
|
||||
bus_no = i2c_get_bus_num();
|
||||
#endif
|
||||
printf("Current bus is %d\n", bus_no);
|
||||
} else {
|
||||
bus_no = simple_strtoul(argv[1], NULL, 10);
|
||||
#if defined(CONFIG_SYS_I2C)
|
||||
if (bus_no >= CONFIG_SYS_NUM_I2C_BUSES) {
|
||||
|
@ -1478,13 +1718,28 @@ static int do_i2c_bus_speed(cmd_tbl_t * cmdtp, int flag, int argc, char * const
|
|||
{
|
||||
int speed, ret=0;
|
||||
|
||||
if (argc == 1)
|
||||
#ifdef CONFIG_DM_I2C
|
||||
struct udevice *bus;
|
||||
|
||||
if (i2c_get_cur_bus(&bus))
|
||||
return 1;
|
||||
#endif
|
||||
if (argc == 1) {
|
||||
#ifdef CONFIG_DM_I2C
|
||||
speed = i2c_get_bus_speed(bus);
|
||||
#else
|
||||
speed = i2c_get_bus_speed();
|
||||
#endif
|
||||
/* querying current speed */
|
||||
printf("Current bus speed=%d\n", i2c_get_bus_speed());
|
||||
else {
|
||||
printf("Current bus speed=%d\n", speed);
|
||||
} else {
|
||||
speed = simple_strtoul(argv[1], NULL, 10);
|
||||
printf("Setting bus speed to %d Hz\n", speed);
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_set_bus_speed(bus, speed);
|
||||
#else
|
||||
ret = i2c_set_bus_speed(speed);
|
||||
#endif
|
||||
if (ret)
|
||||
printf("Failure changing bus speed (%d)\n", ret);
|
||||
}
|
||||
|
@ -1532,7 +1787,16 @@ static int do_i2c_nm(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
|||
*/
|
||||
static int do_i2c_reset(cmd_tbl_t * cmdtp, int flag, int argc, char * const argv[])
|
||||
{
|
||||
#if defined(CONFIG_SYS_I2C)
|
||||
#if defined(CONFIG_DM_I2C)
|
||||
struct udevice *bus;
|
||||
|
||||
if (i2c_get_cur_bus(&bus))
|
||||
return CMD_RET_FAILURE;
|
||||
if (i2c_deblock(bus)) {
|
||||
printf("Error: Not supported by the driver\n");
|
||||
return CMD_RET_FAILURE;
|
||||
}
|
||||
#elif defined(CONFIG_SYS_I2C)
|
||||
i2c_init(I2C_ADAP->speed, I2C_ADAP->slaveaddr);
|
||||
#else
|
||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
||||
|
@ -1546,7 +1810,7 @@ static cmd_tbl_t cmd_i2c_sub[] = {
|
|||
#endif
|
||||
U_BOOT_CMD_MKENT(crc32, 3, 1, do_i2c_crc, "", ""),
|
||||
#if defined(CONFIG_SYS_I2C) || \
|
||||
defined(CONFIG_I2C_MULTI_BUS)
|
||||
defined(CONFIG_I2C_MULTI_BUS) || defined(CONFIG_DM_I2C)
|
||||
U_BOOT_CMD_MKENT(dev, 1, 1, do_i2c_bus_num, "", ""),
|
||||
#endif /* CONFIG_I2C_MULTI_BUS */
|
||||
#if defined(CONFIG_I2C_EDID)
|
||||
|
@ -1560,6 +1824,9 @@ static cmd_tbl_t cmd_i2c_sub[] = {
|
|||
U_BOOT_CMD_MKENT(probe, 0, 1, do_i2c_probe, "", ""),
|
||||
U_BOOT_CMD_MKENT(read, 5, 1, do_i2c_read, "", ""),
|
||||
U_BOOT_CMD_MKENT(write, 5, 0, do_i2c_write, "", ""),
|
||||
#ifdef CONFIG_DM_I2C
|
||||
U_BOOT_CMD_MKENT(flags, 2, 1, do_i2c_flags, "", ""),
|
||||
#endif
|
||||
U_BOOT_CMD_MKENT(reset, 0, 1, do_i2c_reset, "", ""),
|
||||
#if defined(CONFIG_CMD_SDRAM)
|
||||
U_BOOT_CMD_MKENT(sdram, 1, 1, do_sdram, "", ""),
|
||||
|
@ -1610,7 +1877,7 @@ static char i2c_help_text[] =
|
|||
#endif
|
||||
"crc32 chip address[.0, .1, .2] count - compute CRC32 checksum\n"
|
||||
#if defined(CONFIG_SYS_I2C) || \
|
||||
defined(CONFIG_I2C_MULTI_BUS)
|
||||
defined(CONFIG_I2C_MULTI_BUS) || defined(CONFIG_DM_I2C)
|
||||
"i2c dev [dev] - show or set current I2C bus\n"
|
||||
#endif /* CONFIG_I2C_MULTI_BUS */
|
||||
#if defined(CONFIG_I2C_EDID)
|
||||
|
@ -1624,6 +1891,9 @@ static char i2c_help_text[] =
|
|||
"i2c probe [address] - test for and show device(s) on the I2C bus\n"
|
||||
"i2c read chip address[.0, .1, .2] length memaddress - read to memory\n"
|
||||
"i2c write memaddress chip address[.0, .1, .2] length - write memory to i2c\n"
|
||||
#ifdef CONFIG_DM_I2C
|
||||
"i2c flags chip [flags] - set or get chip flags\n"
|
||||
#endif
|
||||
"i2c reset - re-init the I2C Controller\n"
|
||||
#if defined(CONFIG_CMD_SDRAM)
|
||||
"i2c sdram chip - print SDRAM configuration information\n"
|
||||
|
|
5
configs/nyan-big_defconfig
Normal file
5
configs/nyan-big_defconfig
Normal file
|
@ -0,0 +1,5 @@
|
|||
+S:CONFIG_ARM=y
|
||||
+S:CONFIG_TEGRA=y
|
||||
+S:CONFIG_TEGRA124=y
|
||||
+S:CONFIG_TARGET_NYAN_BIG=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="tegra124-nyan-big"
|
|
@ -234,7 +234,7 @@ int device_probe(struct udevice *dev)
|
|||
void *dev_get_platdata(struct udevice *dev)
|
||||
{
|
||||
if (!dev) {
|
||||
dm_warn("%s: null device", __func__);
|
||||
dm_warn("%s: null device\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -244,7 +244,7 @@ void *dev_get_platdata(struct udevice *dev)
|
|||
void *dev_get_priv(struct udevice *dev)
|
||||
{
|
||||
if (!dev) {
|
||||
dm_warn("%s: null device", __func__);
|
||||
dm_warn("%s: null device\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -254,7 +254,7 @@ void *dev_get_priv(struct udevice *dev)
|
|||
void *dev_get_parentdata(struct udevice *dev)
|
||||
{
|
||||
if (!dev) {
|
||||
dm_warn("%s: null device", __func__);
|
||||
dm_warn("%s: null device\n", __func__);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
#
|
||||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
obj-$(CONFIG_DM_I2C) += i2c-uclass.o
|
||||
|
||||
obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o
|
||||
obj-$(CONFIG_I2C_MV) += mv_i2c.o
|
||||
|
@ -26,6 +27,7 @@ obj-$(CONFIG_SYS_I2C_OMAP34XX) += omap24xx_i2c.o
|
|||
obj-$(CONFIG_SYS_I2C_PPC4XX) += ppc4xx_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_RCAR) += rcar_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_S3C24X0) += s3c24x0_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_SANDBOX) += sandbox_i2c.o i2c-emul-uclass.o
|
||||
obj-$(CONFIG_SYS_I2C_SH) += sh_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_SOFT) += soft_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_TEGRA) += tegra_i2c.o
|
||||
|
|
14
drivers/i2c/i2c-emul-uclass.c
Normal file
14
drivers/i2c/i2c-emul-uclass.c
Normal file
|
@ -0,0 +1,14 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
|
||||
UCLASS_DRIVER(i2c_emul) = {
|
||||
.id = UCLASS_I2C_EMUL,
|
||||
.name = "i2c_emul",
|
||||
};
|
466
drivers/i2c/i2c-uclass.c
Normal file
466
drivers/i2c/i2c-uclass.c
Normal file
|
@ -0,0 +1,466 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <malloc.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
#define I2C_MAX_OFFSET_LEN 4
|
||||
|
||||
/**
|
||||
* i2c_setup_offset() - Set up a new message with a chip offset
|
||||
*
|
||||
* @chip: Chip to use
|
||||
* @offset: Byte offset within chip
|
||||
* @offset_buf: Place to put byte offset
|
||||
* @msg: Message buffer
|
||||
* @return 0 if OK, -EADDRNOTAVAIL if the offset length is 0. In that case the
|
||||
* message is still set up but will not contain an offset.
|
||||
*/
|
||||
static int i2c_setup_offset(struct dm_i2c_chip *chip, uint offset,
|
||||
uint8_t offset_buf[], struct i2c_msg *msg)
|
||||
{
|
||||
int offset_len;
|
||||
|
||||
msg->addr = chip->chip_addr;
|
||||
msg->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
|
||||
msg->len = chip->offset_len;
|
||||
msg->buf = offset_buf;
|
||||
if (!chip->offset_len)
|
||||
return -EADDRNOTAVAIL;
|
||||
assert(chip->offset_len <= I2C_MAX_OFFSET_LEN);
|
||||
offset_len = chip->offset_len;
|
||||
while (offset_len--)
|
||||
*offset_buf++ = offset >> (8 * offset_len);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_read_bytewise(struct udevice *dev, uint offset,
|
||||
uint8_t *buffer, int len)
|
||||
{
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct i2c_msg msg[2], *ptr;
|
||||
uint8_t offset_buf[I2C_MAX_OFFSET_LEN];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i2c_setup_offset(chip, offset + i, offset_buf, msg))
|
||||
return -EINVAL;
|
||||
ptr = msg + 1;
|
||||
ptr->addr = chip->chip_addr;
|
||||
ptr->flags = msg->flags | I2C_M_RD;
|
||||
ptr->len = 1;
|
||||
ptr->buf = &buffer[i];
|
||||
ptr++;
|
||||
|
||||
ret = ops->xfer(bus, msg, ptr - msg);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_write_bytewise(struct udevice *dev, uint offset,
|
||||
const uint8_t *buffer, int len)
|
||||
{
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct i2c_msg msg[1];
|
||||
uint8_t buf[I2C_MAX_OFFSET_LEN + 1];
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < len; i++) {
|
||||
if (i2c_setup_offset(chip, offset + i, buf, msg))
|
||||
return -EINVAL;
|
||||
buf[msg->len++] = buffer[i];
|
||||
|
||||
ret = ops->xfer(bus, msg, 1);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer, int len)
|
||||
{
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct i2c_msg msg[2], *ptr;
|
||||
uint8_t offset_buf[I2C_MAX_OFFSET_LEN];
|
||||
int msg_count;
|
||||
|
||||
if (!ops->xfer)
|
||||
return -ENOSYS;
|
||||
if (chip->flags & DM_I2C_CHIP_RD_ADDRESS)
|
||||
return i2c_read_bytewise(dev, offset, buffer, len);
|
||||
ptr = msg;
|
||||
if (!i2c_setup_offset(chip, offset, offset_buf, ptr))
|
||||
ptr++;
|
||||
|
||||
if (len) {
|
||||
ptr->addr = chip->chip_addr;
|
||||
ptr->flags = chip->flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
|
||||
ptr->flags |= I2C_M_RD;
|
||||
ptr->len = len;
|
||||
ptr->buf = buffer;
|
||||
ptr++;
|
||||
}
|
||||
msg_count = ptr - msg;
|
||||
|
||||
return ops->xfer(bus, msg, msg_count);
|
||||
}
|
||||
|
||||
int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer, int len)
|
||||
{
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
struct udevice *bus = dev_get_parent(dev);
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct i2c_msg msg[1];
|
||||
|
||||
if (!ops->xfer)
|
||||
return -ENOSYS;
|
||||
|
||||
if (chip->flags & DM_I2C_CHIP_WR_ADDRESS)
|
||||
return i2c_write_bytewise(dev, offset, buffer, len);
|
||||
/*
|
||||
* The simple approach would be to send two messages here: one to
|
||||
* set the offset and one to write the bytes. However some drivers
|
||||
* will not be expecting this, and some chips won't like how the
|
||||
* driver presents this on the I2C bus.
|
||||
*
|
||||
* The API does not support separate offset and data. We could extend
|
||||
* it with a flag indicating that there is data in the next message
|
||||
* that needs to be processed in the same transaction. We could
|
||||
* instead add an additional buffer to each message. For now, handle
|
||||
* this in the uclass since it isn't clear what the impact on drivers
|
||||
* would be with this extra complication. Unfortunately this means
|
||||
* copying the message.
|
||||
*
|
||||
* Use the stack for small messages, malloc() for larger ones. We
|
||||
* need to allow space for the offset (up to 4 bytes) and the message
|
||||
* itself.
|
||||
*/
|
||||
if (len < 64) {
|
||||
uint8_t buf[I2C_MAX_OFFSET_LEN + len];
|
||||
|
||||
i2c_setup_offset(chip, offset, buf, msg);
|
||||
msg->len += len;
|
||||
memcpy(buf + chip->offset_len, buffer, len);
|
||||
|
||||
return ops->xfer(bus, msg, 1);
|
||||
} else {
|
||||
uint8_t *buf;
|
||||
int ret;
|
||||
|
||||
buf = malloc(I2C_MAX_OFFSET_LEN + len);
|
||||
if (!buf)
|
||||
return -ENOMEM;
|
||||
i2c_setup_offset(chip, offset, buf, msg);
|
||||
msg->len += len;
|
||||
memcpy(buf + chip->offset_len, buffer, len);
|
||||
|
||||
ret = ops->xfer(bus, msg, 1);
|
||||
free(buf);
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* i2c_probe_chip() - probe for a chip on a bus
|
||||
*
|
||||
* @bus: Bus to probe
|
||||
* @chip_addr: Chip address to probe
|
||||
* @flags: Flags for the chip
|
||||
* @return 0 if found, -ENOSYS if the driver is invalid, -EREMOTEIO if the chip
|
||||
* does not respond to probe
|
||||
*/
|
||||
static int i2c_probe_chip(struct udevice *bus, uint chip_addr,
|
||||
enum dm_i2c_chip_flags chip_flags)
|
||||
{
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct i2c_msg msg[1];
|
||||
int ret;
|
||||
|
||||
if (ops->probe_chip) {
|
||||
ret = ops->probe_chip(bus, chip_addr, chip_flags);
|
||||
if (!ret || ret != -ENOSYS)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!ops->xfer)
|
||||
return -ENOSYS;
|
||||
|
||||
/* Probe with a zero-length message */
|
||||
msg->addr = chip_addr;
|
||||
msg->flags = chip_flags & DM_I2C_CHIP_10BIT ? I2C_M_TEN : 0;
|
||||
msg->len = 0;
|
||||
msg->buf = NULL;
|
||||
|
||||
return ops->xfer(bus, msg, 1);
|
||||
}
|
||||
|
||||
static int i2c_bind_driver(struct udevice *bus, uint chip_addr,
|
||||
struct udevice **devp)
|
||||
{
|
||||
struct dm_i2c_chip chip;
|
||||
char name[30], *str;
|
||||
struct udevice *dev;
|
||||
int ret;
|
||||
|
||||
snprintf(name, sizeof(name), "generic_%x", chip_addr);
|
||||
str = strdup(name);
|
||||
ret = device_bind_driver(bus, "i2c_generic_chip_drv", str, &dev);
|
||||
debug("%s: device_bind_driver: ret=%d\n", __func__, ret);
|
||||
if (ret)
|
||||
goto err_bind;
|
||||
|
||||
/* Tell the device what we know about it */
|
||||
memset(&chip, '\0', sizeof(chip));
|
||||
chip.chip_addr = chip_addr;
|
||||
chip.offset_len = 1; /* we assume */
|
||||
ret = device_probe_child(dev, &chip);
|
||||
debug("%s: device_probe_child: ret=%d\n", __func__, ret);
|
||||
if (ret)
|
||||
goto err_probe;
|
||||
|
||||
*devp = dev;
|
||||
return 0;
|
||||
|
||||
err_probe:
|
||||
device_unbind(dev);
|
||||
err_bind:
|
||||
free(str);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp)
|
||||
{
|
||||
struct udevice *dev;
|
||||
|
||||
debug("%s: Searching bus '%s' for address %02x: ", __func__,
|
||||
bus->name, chip_addr);
|
||||
for (device_find_first_child(bus, &dev); dev;
|
||||
device_find_next_child(&dev)) {
|
||||
struct dm_i2c_chip store;
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
int ret;
|
||||
|
||||
if (!chip) {
|
||||
chip = &store;
|
||||
i2c_chip_ofdata_to_platdata(gd->fdt_blob,
|
||||
dev->of_offset, chip);
|
||||
}
|
||||
if (chip->chip_addr == chip_addr) {
|
||||
ret = device_probe(dev);
|
||||
debug("found, ret=%d\n", ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
*devp = dev;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
debug("not found\n");
|
||||
return i2c_bind_driver(bus, chip_addr, devp);
|
||||
}
|
||||
|
||||
int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp)
|
||||
{
|
||||
struct udevice *bus;
|
||||
int ret;
|
||||
|
||||
ret = uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus);
|
||||
if (ret) {
|
||||
debug("Cannot find I2C bus %d\n", busnum);
|
||||
return ret;
|
||||
}
|
||||
ret = i2c_get_chip(bus, chip_addr, devp);
|
||||
if (ret) {
|
||||
debug("Cannot find I2C chip %02x on bus %d\n", chip_addr,
|
||||
busnum);
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
|
||||
struct udevice **devp)
|
||||
{
|
||||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
|
||||
/* First probe that chip */
|
||||
ret = i2c_probe_chip(bus, chip_addr, chip_flags);
|
||||
debug("%s: bus='%s', address %02x, ret=%d\n", __func__, bus->name,
|
||||
chip_addr, ret);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/* The chip was found, see if we have a driver, and probe it */
|
||||
ret = i2c_get_chip(bus, chip_addr, devp);
|
||||
debug("%s: i2c_get_chip: ret=%d\n", __func__, ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
|
||||
{
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct dm_i2c_bus *i2c = bus->uclass_priv;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* If we have a method, call it. If not then the driver probably wants
|
||||
* to deal with speed changes on the next transfer. It can easily read
|
||||
* the current speed from this uclass
|
||||
*/
|
||||
if (ops->set_bus_speed) {
|
||||
ret = ops->set_bus_speed(bus, speed);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
i2c->speed_hz = speed;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* i2c_get_bus_speed:
|
||||
*
|
||||
* Returns speed of selected I2C bus in Hz
|
||||
*/
|
||||
int i2c_get_bus_speed(struct udevice *bus)
|
||||
{
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
struct dm_i2c_bus *i2c = bus->uclass_priv;
|
||||
|
||||
if (!ops->get_bus_speed)
|
||||
return i2c->speed_hz;
|
||||
|
||||
return ops->get_bus_speed(bus);
|
||||
}
|
||||
|
||||
int i2c_set_chip_flags(struct udevice *dev, uint flags)
|
||||
{
|
||||
struct udevice *bus = dev->parent;
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
int ret;
|
||||
|
||||
if (ops->set_flags) {
|
||||
ret = ops->set_flags(dev, flags);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
chip->flags = flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_get_chip_flags(struct udevice *dev, uint *flagsp)
|
||||
{
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
|
||||
*flagsp = chip->flags;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len)
|
||||
{
|
||||
struct dm_i2c_chip *chip = dev_get_parentdata(dev);
|
||||
|
||||
if (offset_len > I2C_MAX_OFFSET_LEN)
|
||||
return -EINVAL;
|
||||
chip->offset_len = offset_len;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int i2c_deblock(struct udevice *bus)
|
||||
{
|
||||
struct dm_i2c_ops *ops = i2c_get_ops(bus);
|
||||
|
||||
/*
|
||||
* We could implement a software deblocking here if we could get
|
||||
* access to the GPIOs used by I2C, and switch them to GPIO mode
|
||||
* and then back to I2C. This is somewhat beyond our powers in
|
||||
* driver model at present, so for now just fail.
|
||||
*
|
||||
* See https://patchwork.ozlabs.org/patch/399040/
|
||||
*/
|
||||
if (!ops->deblock)
|
||||
return -ENOSYS;
|
||||
|
||||
return ops->deblock(bus);
|
||||
}
|
||||
|
||||
int i2c_chip_ofdata_to_platdata(const void *blob, int node,
|
||||
struct dm_i2c_chip *chip)
|
||||
{
|
||||
chip->offset_len = 1; /* default */
|
||||
chip->flags = 0;
|
||||
chip->chip_addr = fdtdec_get_int(gd->fdt_blob, node, "reg", -1);
|
||||
if (chip->chip_addr == -1) {
|
||||
debug("%s: I2C Node '%s' has no 'reg' property\n", __func__,
|
||||
fdt_get_name(blob, node, NULL));
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_post_probe(struct udevice *dev)
|
||||
{
|
||||
struct dm_i2c_bus *i2c = dev->uclass_priv;
|
||||
|
||||
i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
|
||||
"clock-frequency", 100000);
|
||||
|
||||
return i2c_set_bus_speed(dev, i2c->speed_hz);
|
||||
}
|
||||
|
||||
int i2c_post_bind(struct udevice *dev)
|
||||
{
|
||||
/* Scan the bus for devices */
|
||||
return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
|
||||
}
|
||||
|
||||
UCLASS_DRIVER(i2c) = {
|
||||
.id = UCLASS_I2C,
|
||||
.name = "i2c",
|
||||
.per_device_auto_alloc_size = sizeof(struct dm_i2c_bus),
|
||||
.post_bind = i2c_post_bind,
|
||||
.post_probe = i2c_post_probe,
|
||||
};
|
||||
|
||||
UCLASS_DRIVER(i2c_generic) = {
|
||||
.id = UCLASS_I2C_GENERIC,
|
||||
.name = "i2c_generic",
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(i2c_generic_chip_drv) = {
|
||||
.name = "i2c_generic_chip_drv",
|
||||
.id = UCLASS_I2C_GENERIC,
|
||||
};
|
111
drivers/i2c/sandbox_i2c.c
Normal file
111
drivers/i2c/sandbox_i2c.c
Normal file
|
@ -0,0 +1,111 @@
|
|||
/*
|
||||
* Simulate an I2C port
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/test.h>
|
||||
#include <dm/lists.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/root.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct dm_sandbox_i2c_emul_priv {
|
||||
struct udevice *emul;
|
||||
};
|
||||
|
||||
static int get_emul(struct udevice *dev, struct udevice **devp,
|
||||
struct dm_i2c_ops **opsp)
|
||||
{
|
||||
struct dm_i2c_chip *priv;
|
||||
int ret;
|
||||
|
||||
*devp = NULL;
|
||||
*opsp = NULL;
|
||||
priv = dev_get_parentdata(dev);
|
||||
if (!priv->emul) {
|
||||
ret = dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset,
|
||||
false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = device_get_child(dev, 0, &priv->emul);
|
||||
if (ret)
|
||||
return ret;
|
||||
}
|
||||
*devp = priv->emul;
|
||||
*opsp = i2c_get_ops(priv->emul);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
|
||||
int nmsgs)
|
||||
{
|
||||
struct dm_i2c_bus *i2c = bus->uclass_priv;
|
||||
struct dm_i2c_ops *ops;
|
||||
struct udevice *emul, *dev;
|
||||
bool is_read;
|
||||
int ret;
|
||||
|
||||
/* Special test code to return success but with no emulation */
|
||||
if (msg->addr == SANDBOX_I2C_TEST_ADDR)
|
||||
return 0;
|
||||
|
||||
ret = i2c_get_chip(bus, msg->addr, &dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = get_emul(dev, &emul, &ops);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* For testing, don't allow writing above 100KHz for writes and
|
||||
* 400KHz for reads
|
||||
*/
|
||||
is_read = nmsgs > 1;
|
||||
if (i2c->speed_hz > (is_read ? 400000 : 100000))
|
||||
return -EINVAL;
|
||||
return ops->xfer(emul, msg, nmsgs);
|
||||
}
|
||||
|
||||
static const struct dm_i2c_ops sandbox_i2c_ops = {
|
||||
.xfer = sandbox_i2c_xfer,
|
||||
};
|
||||
|
||||
static int sandbox_i2c_child_pre_probe(struct udevice *dev)
|
||||
{
|
||||
struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
|
||||
|
||||
/* Ignore our test address */
|
||||
if (i2c_chip->chip_addr == SANDBOX_I2C_TEST_ADDR)
|
||||
return 0;
|
||||
if (dev->of_offset == -1)
|
||||
return 0;
|
||||
|
||||
return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
|
||||
i2c_chip);
|
||||
}
|
||||
|
||||
static const struct udevice_id sandbox_i2c_ids[] = {
|
||||
{ .compatible = "sandbox,i2c" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(i2c_sandbox) = {
|
||||
.name = "i2c_sandbox",
|
||||
.id = UCLASS_I2C,
|
||||
.of_match = sandbox_i2c_ids,
|
||||
.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
|
||||
.child_pre_probe = sandbox_i2c_child_pre_probe,
|
||||
.ops = &sandbox_i2c_ops,
|
||||
};
|
|
@ -7,6 +7,8 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
|
@ -19,6 +21,12 @@
|
|||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum i2c_type {
|
||||
TYPE_114,
|
||||
TYPE_STD,
|
||||
TYPE_DVC,
|
||||
};
|
||||
|
||||
/* Information about i2c controller */
|
||||
struct i2c_bus {
|
||||
int id;
|
||||
|
@ -27,20 +35,17 @@ struct i2c_bus {
|
|||
int pinmux_config;
|
||||
struct i2c_control *control;
|
||||
struct i2c_ctlr *regs;
|
||||
int is_dvc; /* DVC type, rather than I2C */
|
||||
int is_scs; /* single clock source (T114+) */
|
||||
enum i2c_type type;
|
||||
int inited; /* bus is inited */
|
||||
};
|
||||
|
||||
static struct i2c_bus i2c_controllers[TEGRA_I2C_NUM_CONTROLLERS];
|
||||
|
||||
static void set_packet_mode(struct i2c_bus *i2c_bus)
|
||||
{
|
||||
u32 config;
|
||||
|
||||
config = I2C_CNFG_NEW_MASTER_FSM_MASK | I2C_CNFG_PACKET_MODE_MASK;
|
||||
|
||||
if (i2c_bus->is_dvc) {
|
||||
if (i2c_bus->type == TYPE_DVC) {
|
||||
struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
|
||||
|
||||
writel(config, &dvc->cnfg);
|
||||
|
@ -65,6 +70,9 @@ static void i2c_reset_controller(struct i2c_bus *i2c_bus)
|
|||
|
||||
static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
||||
{
|
||||
if (!i2c_bus->speed)
|
||||
return;
|
||||
debug("%s: speed=%d\n", __func__, i2c_bus->speed);
|
||||
/*
|
||||
* Use PLLP - DP-04508-001_v06 datasheet indicates a divisor of 8
|
||||
* here, in section 23.3.1, but in fact we seem to need a factor of
|
||||
|
@ -73,7 +81,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
|||
clock_start_periph_pll(i2c_bus->periph_id, CLOCK_ID_PERIPH,
|
||||
i2c_bus->speed * 2 * 8);
|
||||
|
||||
if (i2c_bus->is_scs) {
|
||||
if (i2c_bus->type == TYPE_114) {
|
||||
/*
|
||||
* T114 I2C went to a single clock source for standard/fast and
|
||||
* HS clock speeds. The new clock rate setting calculation is:
|
||||
|
@ -98,7 +106,7 @@ static void i2c_init_controller(struct i2c_bus *i2c_bus)
|
|||
i2c_reset_controller(i2c_bus);
|
||||
|
||||
/* Configure I2C controller. */
|
||||
if (i2c_bus->is_dvc) { /* only for DVC I2C */
|
||||
if (i2c_bus->type == TYPE_DVC) { /* only for DVC I2C */
|
||||
struct dvc_ctlr *dvc = (struct dvc_ctlr *)i2c_bus->regs;
|
||||
|
||||
setbits_le32(&dvc->ctrl3, DVC_CTRL_REG3_I2C_HW_SW_PROG_MASK);
|
||||
|
@ -272,7 +280,7 @@ exit:
|
|||
return error;
|
||||
}
|
||||
|
||||
static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data,
|
||||
static int tegra_i2c_write_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data,
|
||||
u32 len, bool end_with_repeated_start)
|
||||
{
|
||||
int error;
|
||||
|
@ -286,14 +294,14 @@ static int tegra_i2c_write_data(struct i2c_bus *bus, u32 addr, u8 *data,
|
|||
trans_info.num_bytes = len;
|
||||
trans_info.is_10bit_address = 0;
|
||||
|
||||
error = send_recv_packets(bus, &trans_info);
|
||||
error = send_recv_packets(i2c_bus, &trans_info);
|
||||
if (error)
|
||||
debug("tegra_i2c_write_data: Error (%d) !!!\n", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
static int tegra_i2c_read_data(struct i2c_bus *bus, u32 addr, u8 *data,
|
||||
static int tegra_i2c_read_data(struct i2c_bus *i2c_bus, u32 addr, u8 *data,
|
||||
u32 len)
|
||||
{
|
||||
int error;
|
||||
|
@ -305,52 +313,32 @@ static int tegra_i2c_read_data(struct i2c_bus *bus, u32 addr, u8 *data,
|
|||
trans_info.num_bytes = len;
|
||||
trans_info.is_10bit_address = 0;
|
||||
|
||||
error = send_recv_packets(bus, &trans_info);
|
||||
error = send_recv_packets(i2c_bus, &trans_info);
|
||||
if (error)
|
||||
debug("tegra_i2c_read_data: Error (%d) !!!\n", error);
|
||||
|
||||
return error;
|
||||
}
|
||||
|
||||
#ifndef CONFIG_OF_CONTROL
|
||||
#error "Please enable device tree support to use this driver"
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Check that a bus number is valid and return a pointer to it
|
||||
*
|
||||
* @param bus_num Bus number to check / return
|
||||
* @return pointer to bus, if valid, else NULL
|
||||
*/
|
||||
static struct i2c_bus *tegra_i2c_get_bus(struct i2c_adapter *adap)
|
||||
static int tegra_i2c_set_bus_speed(struct udevice *dev, unsigned int speed)
|
||||
{
|
||||
struct i2c_bus *bus;
|
||||
struct i2c_bus *i2c_bus = dev_get_priv(dev);
|
||||
|
||||
bus = &i2c_controllers[adap->hwadapnr];
|
||||
if (!bus->inited) {
|
||||
debug("%s: Bus %u not available\n", __func__, adap->hwadapnr);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return bus;
|
||||
}
|
||||
|
||||
static unsigned int tegra_i2c_set_bus_speed(struct i2c_adapter *adap,
|
||||
unsigned int speed)
|
||||
{
|
||||
struct i2c_bus *bus;
|
||||
|
||||
bus = tegra_i2c_get_bus(adap);
|
||||
if (!bus)
|
||||
return 0;
|
||||
bus->speed = speed;
|
||||
i2c_init_controller(bus);
|
||||
i2c_bus->speed = speed;
|
||||
i2c_init_controller(i2c_bus);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
|
||||
static int tegra_i2c_probe(struct udevice *dev)
|
||||
{
|
||||
struct i2c_bus *i2c_bus = dev_get_priv(dev);
|
||||
const void *blob = gd->fdt_blob;
|
||||
int node = dev->of_offset;
|
||||
bool is_dvc;
|
||||
|
||||
i2c_bus->id = dev->seq;
|
||||
i2c_bus->type = dev_get_of_data(dev);
|
||||
i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");
|
||||
|
||||
/*
|
||||
|
@ -358,7 +346,6 @@ static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
|
|||
* far no one needs anything other than the default.
|
||||
*/
|
||||
i2c_bus->pinmux_config = FUNCMUX_DEFAULT;
|
||||
i2c_bus->speed = fdtdec_get_int(blob, node, "clock-frequency", 0);
|
||||
i2c_bus->periph_id = clock_decode_periph_id(blob, node);
|
||||
|
||||
/*
|
||||
|
@ -371,107 +358,25 @@ static int i2c_get_config(const void *blob, int node, struct i2c_bus *i2c_bus)
|
|||
* i2c_bus->pinmux_config = FUNCMUX_I2C2_PTA;
|
||||
*/
|
||||
if (i2c_bus->periph_id == -1)
|
||||
return -FDT_ERR_NOTFOUND;
|
||||
return -EINVAL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a list of nodes, adding them to our list of I2C ports.
|
||||
*
|
||||
* @param blob fdt blob
|
||||
* @param node_list list of nodes to process (any <=0 are ignored)
|
||||
* @param count number of nodes to process
|
||||
* @param is_dvc 1 if these are DVC ports, 0 if standard I2C
|
||||
* @param is_scs 1 if this HW uses a single clock source (T114+)
|
||||
* @return 0 if ok, -1 on error
|
||||
*/
|
||||
static int process_nodes(const void *blob, int node_list[], int count,
|
||||
int is_dvc, int is_scs)
|
||||
{
|
||||
struct i2c_bus *i2c_bus;
|
||||
int i;
|
||||
|
||||
/* build the i2c_controllers[] for each controller */
|
||||
for (i = 0; i < count; i++) {
|
||||
int node = node_list[i];
|
||||
|
||||
if (node <= 0)
|
||||
continue;
|
||||
|
||||
i2c_bus = &i2c_controllers[i];
|
||||
i2c_bus->id = i;
|
||||
|
||||
if (i2c_get_config(blob, node, i2c_bus)) {
|
||||
printf("i2c_init_board: failed to decode bus %d\n", i);
|
||||
return -1;
|
||||
}
|
||||
|
||||
i2c_bus->is_scs = is_scs;
|
||||
|
||||
i2c_bus->is_dvc = is_dvc;
|
||||
is_dvc = dev_get_of_data(dev) == TYPE_DVC;
|
||||
if (is_dvc) {
|
||||
i2c_bus->control =
|
||||
&((struct dvc_ctlr *)i2c_bus->regs)->control;
|
||||
} else {
|
||||
i2c_bus->control = &i2c_bus->regs->control;
|
||||
}
|
||||
debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
|
||||
is_dvc ? "dvc" : "i2c", i, i2c_bus->regs,
|
||||
i2c_bus->periph_id, i2c_bus->speed);
|
||||
i2c_init_controller(i2c_bus);
|
||||
debug("ok\n");
|
||||
i2c_bus->inited = 1;
|
||||
|
||||
/* Mark position as used */
|
||||
node_list[i] = -1;
|
||||
}
|
||||
debug("%s: controller bus %d at %p, periph_id %d, speed %d: ",
|
||||
is_dvc ? "dvc" : "i2c", dev->seq, i2c_bus->regs,
|
||||
i2c_bus->periph_id, i2c_bus->speed);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Sadly there is no error return from this function */
|
||||
void i2c_init_board(void)
|
||||
{
|
||||
int node_list[TEGRA_I2C_NUM_CONTROLLERS];
|
||||
const void *blob = gd->fdt_blob;
|
||||
int count;
|
||||
|
||||
/* First check for newer (T114+) I2C ports */
|
||||
count = fdtdec_find_aliases_for_id(blob, "i2c",
|
||||
COMPAT_NVIDIA_TEGRA114_I2C, node_list,
|
||||
TEGRA_I2C_NUM_CONTROLLERS);
|
||||
if (process_nodes(blob, node_list, count, 0, 1))
|
||||
return;
|
||||
|
||||
/* Now get the older (T20/T30) normal I2C ports */
|
||||
count = fdtdec_find_aliases_for_id(blob, "i2c",
|
||||
COMPAT_NVIDIA_TEGRA20_I2C, node_list,
|
||||
TEGRA_I2C_NUM_CONTROLLERS);
|
||||
if (process_nodes(blob, node_list, count, 0, 0))
|
||||
return;
|
||||
|
||||
/* Now look for dvc ports */
|
||||
count = fdtdec_add_aliases_for_id(blob, "i2c",
|
||||
COMPAT_NVIDIA_TEGRA20_DVC, node_list,
|
||||
TEGRA_I2C_NUM_CONTROLLERS);
|
||||
if (process_nodes(blob, node_list, count, 1, 0))
|
||||
return;
|
||||
}
|
||||
|
||||
static void tegra_i2c_init(struct i2c_adapter *adap, int speed, int slaveaddr)
|
||||
{
|
||||
/* No i2c support prior to relocation */
|
||||
if (!(gd->flags & GD_FLG_RELOC))
|
||||
return;
|
||||
|
||||
/* This will override the speed selected in the fdt for that port */
|
||||
debug("i2c_init(speed=%u, slaveaddr=0x%x)\n", speed, slaveaddr);
|
||||
i2c_set_bus_speed(speed);
|
||||
}
|
||||
|
||||
/* i2c write version without the register address */
|
||||
static int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
|
||||
static int i2c_write_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer,
|
||||
int len, bool end_with_repeated_start)
|
||||
{
|
||||
int rc;
|
||||
|
@ -484,7 +389,7 @@ static int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
|
|||
debug("\n");
|
||||
|
||||
/* Shift 7-bit address over for lower-level i2c functions */
|
||||
rc = tegra_i2c_write_data(bus, chip << 1, buffer, len,
|
||||
rc = tegra_i2c_write_data(i2c_bus, chip << 1, buffer, len,
|
||||
end_with_repeated_start);
|
||||
if (rc)
|
||||
debug("i2c_write_data(): rc=%d\n", rc);
|
||||
|
@ -493,14 +398,14 @@ static int i2c_write_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
|
|||
}
|
||||
|
||||
/* i2c read version without the register address */
|
||||
static int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
|
||||
static int i2c_read_data(struct i2c_bus *i2c_bus, uchar chip, uchar *buffer,
|
||||
int len)
|
||||
{
|
||||
int rc;
|
||||
|
||||
debug("inside i2c_read_data():\n");
|
||||
/* Shift 7-bit address over for lower-level i2c functions */
|
||||
rc = tegra_i2c_read_data(bus, chip << 1, buffer, len);
|
||||
rc = tegra_i2c_read_data(i2c_bus, chip << 1, buffer, len);
|
||||
if (rc) {
|
||||
debug("i2c_read_data(): rc=%d\n", rc);
|
||||
return rc;
|
||||
|
@ -516,132 +421,99 @@ static int i2c_read_data(struct i2c_bus *bus, uchar chip, uchar *buffer,
|
|||
}
|
||||
|
||||
/* Probe to see if a chip is present. */
|
||||
static int tegra_i2c_probe(struct i2c_adapter *adap, uchar chip)
|
||||
static int tegra_i2c_probe_chip(struct udevice *bus, uint chip_addr,
|
||||
uint chip_flags)
|
||||
{
|
||||
struct i2c_bus *bus;
|
||||
struct i2c_bus *i2c_bus = dev_get_priv(bus);
|
||||
int rc;
|
||||
uchar reg;
|
||||
u8 reg;
|
||||
|
||||
debug("i2c_probe: addr=0x%x\n", chip);
|
||||
bus = tegra_i2c_get_bus(adap);
|
||||
if (!bus)
|
||||
return 1;
|
||||
reg = 0;
|
||||
rc = i2c_write_data(bus, chip, ®, 1, false);
|
||||
if (rc) {
|
||||
debug("Error probing 0x%x.\n", chip);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
/* Shift 7-bit address over for lower-level i2c functions */
|
||||
rc = tegra_i2c_write_data(i2c_bus, chip_addr << 1, ®, sizeof(reg),
|
||||
false);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int i2c_addr_ok(const uint addr, const int alen)
|
||||
static int tegra_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
|
||||
int nmsgs)
|
||||
{
|
||||
/* We support 7 or 10 bit addresses, so one or two bytes each */
|
||||
return alen == 1 || alen == 2;
|
||||
}
|
||||
struct i2c_bus *i2c_bus = dev_get_priv(bus);
|
||||
int ret;
|
||||
|
||||
/* Read bytes */
|
||||
static int tegra_i2c_read(struct i2c_adapter *adap, uchar chip, uint addr,
|
||||
int alen, uchar *buffer, int len)
|
||||
{
|
||||
struct i2c_bus *bus;
|
||||
uint offset;
|
||||
int i;
|
||||
debug("i2c_xfer: %d messages\n", nmsgs);
|
||||
for (; nmsgs > 0; nmsgs--, msg++) {
|
||||
bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
|
||||
|
||||
debug("i2c_read: chip=0x%x, addr=0x%x, alen=0x%x len=0x%x\n",
|
||||
chip, addr, alen, len);
|
||||
bus = tegra_i2c_get_bus(adap);
|
||||
if (!bus)
|
||||
return 1;
|
||||
if (!i2c_addr_ok(addr, alen)) {
|
||||
debug("i2c_read: Bad address %x.%d.\n", addr, alen);
|
||||
return 1;
|
||||
debug("i2c_xfer: chip=0x%x, len=0x%x\n", msg->addr, msg->len);
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
ret = i2c_read_data(i2c_bus, msg->addr, msg->buf,
|
||||
msg->len);
|
||||
} else {
|
||||
ret = i2c_write_data(i2c_bus, msg->addr, msg->buf,
|
||||
msg->len, next_is_read);
|
||||
}
|
||||
for (offset = 0; offset < len; offset++) {
|
||||
if (alen) {
|
||||
uchar data[alen];
|
||||
for (i = 0; i < alen; i++) {
|
||||
data[alen - i - 1] =
|
||||
(addr + offset) >> (8 * i);
|
||||
}
|
||||
if (i2c_write_data(bus, chip, data, alen, true)) {
|
||||
debug("i2c_read: error sending (0x%x)\n",
|
||||
addr);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (i2c_read_data(bus, chip, buffer + offset, 1)) {
|
||||
debug("i2c_read: error reading (0x%x)\n", addr);
|
||||
return 1;
|
||||
if (ret) {
|
||||
debug("i2c_write: error sending\n");
|
||||
return -EREMOTEIO;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Write bytes */
|
||||
static int tegra_i2c_write(struct i2c_adapter *adap, uchar chip, uint addr,
|
||||
int alen, uchar *buffer, int len)
|
||||
int tegra_i2c_get_dvc_bus(struct udevice **busp)
|
||||
{
|
||||
struct i2c_bus *bus;
|
||||
uint offset;
|
||||
int i;
|
||||
struct udevice *bus;
|
||||
|
||||
debug("i2c_write: chip=0x%x, addr=0x%x, alen=0x%x len=0x%x\n",
|
||||
chip, addr, alen, len);
|
||||
bus = tegra_i2c_get_bus(adap);
|
||||
if (!bus)
|
||||
return 1;
|
||||
if (!i2c_addr_ok(addr, alen)) {
|
||||
debug("i2c_write: Bad address %x.%d.\n", addr, alen);
|
||||
return 1;
|
||||
}
|
||||
for (offset = 0; offset < len; offset++) {
|
||||
uchar data[alen + 1];
|
||||
for (i = 0; i < alen; i++)
|
||||
data[alen - i - 1] = (addr + offset) >> (8 * i);
|
||||
data[alen] = buffer[offset];
|
||||
if (i2c_write_data(bus, chip, data, alen + 1, false)) {
|
||||
debug("i2c_write: error sending (0x%x)\n", addr);
|
||||
return 1;
|
||||
for (uclass_first_device(UCLASS_I2C, &bus);
|
||||
bus;
|
||||
uclass_next_device(&bus)) {
|
||||
if (dev_get_of_data(bus) == TYPE_DVC) {
|
||||
*busp = bus;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static const struct dm_i2c_ops tegra_i2c_ops = {
|
||||
.xfer = tegra_i2c_xfer,
|
||||
.probe_chip = tegra_i2c_probe_chip,
|
||||
.set_bus_speed = tegra_i2c_set_bus_speed,
|
||||
};
|
||||
|
||||
static int tegra_i2c_child_pre_probe(struct udevice *dev)
|
||||
{
|
||||
struct dm_i2c_chip *i2c_chip = dev_get_parentdata(dev);
|
||||
|
||||
if (dev->of_offset == -1)
|
||||
return 0;
|
||||
return i2c_chip_ofdata_to_platdata(gd->fdt_blob, dev->of_offset,
|
||||
i2c_chip);
|
||||
}
|
||||
|
||||
static int tegra_i2c_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int tegra_i2c_get_dvc_bus_num(void)
|
||||
{
|
||||
int i;
|
||||
static const struct udevice_id tegra_i2c_ids[] = {
|
||||
{ .compatible = "nvidia,tegra114-i2c", .data = TYPE_114 },
|
||||
{ .compatible = "nvidia,tegra20-i2c", .data = TYPE_STD },
|
||||
{ .compatible = "nvidia,tegra20-i2c-dvc", .data = TYPE_DVC },
|
||||
{ }
|
||||
};
|
||||
|
||||
for (i = 0; i < TEGRA_I2C_NUM_CONTROLLERS; i++) {
|
||||
struct i2c_bus *bus = &i2c_controllers[i];
|
||||
|
||||
if (bus->inited && bus->is_dvc)
|
||||
return i;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Register soft i2c adapters
|
||||
*/
|
||||
U_BOOT_I2C_ADAP_COMPLETE(tegra0, tegra_i2c_init, tegra_i2c_probe,
|
||||
tegra_i2c_read, tegra_i2c_write,
|
||||
tegra_i2c_set_bus_speed, 100000, 0, 0)
|
||||
U_BOOT_I2C_ADAP_COMPLETE(tegra1, tegra_i2c_init, tegra_i2c_probe,
|
||||
tegra_i2c_read, tegra_i2c_write,
|
||||
tegra_i2c_set_bus_speed, 100000, 0, 1)
|
||||
U_BOOT_I2C_ADAP_COMPLETE(tegra2, tegra_i2c_init, tegra_i2c_probe,
|
||||
tegra_i2c_read, tegra_i2c_write,
|
||||
tegra_i2c_set_bus_speed, 100000, 0, 2)
|
||||
U_BOOT_I2C_ADAP_COMPLETE(tegra3, tegra_i2c_init, tegra_i2c_probe,
|
||||
tegra_i2c_read, tegra_i2c_write,
|
||||
tegra_i2c_set_bus_speed, 100000, 0, 3)
|
||||
#if TEGRA_I2C_NUM_CONTROLLERS > 4
|
||||
U_BOOT_I2C_ADAP_COMPLETE(tegra4, tegra_i2c_init, tegra_i2c_probe,
|
||||
tegra_i2c_read, tegra_i2c_write,
|
||||
tegra_i2c_set_bus_speed, 100000, 0, 4)
|
||||
#endif
|
||||
U_BOOT_DRIVER(i2c_tegra) = {
|
||||
.name = "i2c_tegra",
|
||||
.id = UCLASS_I2C,
|
||||
.of_match = tegra_i2c_ids,
|
||||
.ofdata_to_platdata = tegra_i2c_ofdata_to_platdata,
|
||||
.probe = tegra_i2c_probe,
|
||||
.per_child_auto_alloc_size = sizeof(struct dm_i2c_chip),
|
||||
.child_pre_probe = tegra_i2c_child_pre_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct i2c_bus),
|
||||
.ops = &tegra_i2c_ops,
|
||||
};
|
||||
|
|
|
@ -15,11 +15,15 @@ obj-$(CONFIG_CROS_EC_SANDBOX) += cros_ec_sandbox.o
|
|||
obj-$(CONFIG_CROS_EC_SPI) += cros_ec_spi.o
|
||||
obj-$(CONFIG_FSL_IIM) += fsl_iim.o
|
||||
obj-$(CONFIG_GPIO_LED) += gpio_led.o
|
||||
obj-$(CONFIG_I2C_EEPROM) += i2c_eeprom.o
|
||||
obj-$(CONFIG_FSL_MC9SDZ60) += mc9sdz60.o
|
||||
obj-$(CONFIG_MXC_OCOTP) += mxc_ocotp.o
|
||||
obj-$(CONFIG_MXS_OCOTP) += mxs_ocotp.o
|
||||
obj-$(CONFIG_NS87308) += ns87308.o
|
||||
obj-$(CONFIG_PDSP188x) += pdsp188x.o
|
||||
ifdef CONFIG_DM_I2C
|
||||
obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
|
||||
endif
|
||||
obj-$(CONFIG_STATUS_LED) += status_led.o
|
||||
obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
|
||||
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
|
||||
|
|
51
drivers/misc/i2c_eeprom.c
Normal file
51
drivers/misc/i2c_eeprom.c
Normal file
|
@ -0,0 +1,51 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <i2c_eeprom.h>
|
||||
|
||||
static int i2c_eeprom_read(struct udevice *dev, int offset, uint8_t *buf,
|
||||
int size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
static int i2c_eeprom_write(struct udevice *dev, int offset,
|
||||
const uint8_t *buf, int size)
|
||||
{
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
struct i2c_eeprom_ops i2c_eeprom_std_ops = {
|
||||
.read = i2c_eeprom_read,
|
||||
.write = i2c_eeprom_write,
|
||||
};
|
||||
|
||||
int i2c_eeprom_std_probe(struct udevice *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id i2c_eeprom_std_ids[] = {
|
||||
{ .compatible = "i2c-eeprom" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(i2c_eeprom_std) = {
|
||||
.name = "i2c_eeprom",
|
||||
.id = UCLASS_I2C_EEPROM,
|
||||
.of_match = i2c_eeprom_std_ids,
|
||||
.probe = i2c_eeprom_std_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct i2c_eeprom),
|
||||
.ops = &i2c_eeprom_std_ops,
|
||||
};
|
||||
|
||||
UCLASS_DRIVER(i2c_eeprom) = {
|
||||
.id = UCLASS_I2C_EEPROM,
|
||||
.name = "i2c_eeprom",
|
||||
};
|
168
drivers/misc/i2c_eeprom_emul.c
Normal file
168
drivers/misc/i2c_eeprom_emul.c
Normal file
|
@ -0,0 +1,168 @@
|
|||
/*
|
||||
* Simulate an I2C eeprom
|
||||
*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/test.h>
|
||||
|
||||
#ifdef DEBUG
|
||||
#define debug_buffer print_buffer
|
||||
#else
|
||||
#define debug_buffer(x, ...)
|
||||
#endif
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct sandbox_i2c_flash_plat_data {
|
||||
enum sandbox_i2c_eeprom_test_mode test_mode;
|
||||
const char *filename;
|
||||
int offset_len; /* Length of an offset in bytes */
|
||||
int size; /* Size of data buffer */
|
||||
};
|
||||
|
||||
struct sandbox_i2c_flash {
|
||||
uint8_t *data;
|
||||
};
|
||||
|
||||
void sandbox_i2c_eeprom_set_test_mode(struct udevice *dev,
|
||||
enum sandbox_i2c_eeprom_test_mode mode)
|
||||
{
|
||||
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
|
||||
|
||||
plat->test_mode = mode;
|
||||
}
|
||||
|
||||
void sandbox_i2c_eeprom_set_offset_len(struct udevice *dev, int offset_len)
|
||||
{
|
||||
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
|
||||
|
||||
plat->offset_len = offset_len;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_eeprom_xfer(struct udevice *emul, struct i2c_msg *msg,
|
||||
int nmsgs)
|
||||
{
|
||||
struct sandbox_i2c_flash *priv = dev_get_priv(emul);
|
||||
uint offset = 0;
|
||||
|
||||
debug("\n%s\n", __func__);
|
||||
debug_buffer(0, priv->data, 1, 16, 0);
|
||||
for (; nmsgs > 0; nmsgs--, msg++) {
|
||||
struct sandbox_i2c_flash_plat_data *plat =
|
||||
dev_get_platdata(emul);
|
||||
int len;
|
||||
u8 *ptr;
|
||||
|
||||
if (!plat->size)
|
||||
return -ENODEV;
|
||||
if (msg->addr + msg->len > plat->size) {
|
||||
debug("%s: Address %x, len %x is outside range 0..%x\n",
|
||||
__func__, msg->addr, msg->len, plat->size);
|
||||
return -EINVAL;
|
||||
}
|
||||
len = msg->len;
|
||||
debug(" %s: msg->len=%d",
|
||||
msg->flags & I2C_M_RD ? "read" : "write",
|
||||
msg->len);
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
|
||||
len = 1;
|
||||
debug(", offset %x, len %x: ", offset, len);
|
||||
memcpy(msg->buf, priv->data + offset, len);
|
||||
memset(msg->buf + len, '\xff', msg->len - len);
|
||||
debug_buffer(0, msg->buf, 1, msg->len, 0);
|
||||
} else if (len >= plat->offset_len) {
|
||||
int i;
|
||||
|
||||
ptr = msg->buf;
|
||||
for (i = 0; i < plat->offset_len; i++, len--)
|
||||
offset = (offset << 8) | *ptr++;
|
||||
debug(", set offset %x: ", offset);
|
||||
debug_buffer(0, msg->buf, 1, msg->len, 0);
|
||||
if (plat->test_mode == SIE_TEST_MODE_SINGLE_BYTE)
|
||||
len = min(len, 1);
|
||||
|
||||
/* For testing, map offsets into our limited buffer */
|
||||
for (i = 24; i > 0; i -= 8) {
|
||||
if (offset > (1 << i)) {
|
||||
offset = (offset >> i) |
|
||||
(offset & ((1 << i) - 1));
|
||||
offset += i;
|
||||
}
|
||||
}
|
||||
memcpy(priv->data + offset, ptr, len);
|
||||
}
|
||||
}
|
||||
debug_buffer(0, priv->data, 1, 16, 0);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dm_i2c_ops sandbox_i2c_emul_ops = {
|
||||
.xfer = sandbox_i2c_eeprom_xfer,
|
||||
};
|
||||
|
||||
static int sandbox_i2c_eeprom_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
|
||||
|
||||
plat->size = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
|
||||
"sandbox,size", 32);
|
||||
plat->filename = fdt_getprop(gd->fdt_blob, dev->of_offset,
|
||||
"sandbox,filename", NULL);
|
||||
if (!plat->filename) {
|
||||
debug("%s: No filename for device '%s'\n", __func__,
|
||||
dev->name);
|
||||
return -EINVAL;
|
||||
}
|
||||
plat->test_mode = SIE_TEST_MODE_NONE;
|
||||
plat->offset_len = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_eeprom_probe(struct udevice *dev)
|
||||
{
|
||||
struct sandbox_i2c_flash_plat_data *plat = dev_get_platdata(dev);
|
||||
struct sandbox_i2c_flash *priv = dev_get_priv(dev);
|
||||
|
||||
priv->data = calloc(1, plat->size);
|
||||
if (!priv->data)
|
||||
return -ENOMEM;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int sandbox_i2c_eeprom_remove(struct udevice *dev)
|
||||
{
|
||||
struct sandbox_i2c_flash *priv = dev_get_priv(dev);
|
||||
|
||||
free(priv->data);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct udevice_id sandbox_i2c_ids[] = {
|
||||
{ .compatible = "sandbox,i2c-eeprom" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(sandbox_i2c_emul) = {
|
||||
.name = "sandbox_i2c_eeprom_emul",
|
||||
.id = UCLASS_I2C_EMUL,
|
||||
.of_match = sandbox_i2c_ids,
|
||||
.ofdata_to_platdata = sandbox_i2c_eeprom_ofdata_to_platdata,
|
||||
.probe = sandbox_i2c_eeprom_probe,
|
||||
.remove = sandbox_i2c_eeprom_remove,
|
||||
.priv_auto_alloc_size = sizeof(struct sandbox_i2c_flash),
|
||||
.platdata_auto_alloc_size = sizeof(struct sandbox_i2c_flash_plat_data),
|
||||
.ops = &sandbox_i2c_emul_ops,
|
||||
};
|
|
@ -10,9 +10,7 @@
|
|||
#include <asm/io.h>
|
||||
#include <i2c.h>
|
||||
|
||||
static int bus_num; /* I2C bus we are on */
|
||||
#define I2C_ADDRESS 0x34 /* chip requires this address */
|
||||
static char inited; /* 1 if we have been inited */
|
||||
static struct udevice *tps6586x_dev;
|
||||
|
||||
enum {
|
||||
/* Registers that we access */
|
||||
|
@ -37,13 +35,9 @@ static int tps6586x_read(int reg)
|
|||
int i;
|
||||
uchar data;
|
||||
int retval = -1;
|
||||
int old_bus_num;
|
||||
|
||||
old_bus_num = i2c_get_bus_num();
|
||||
i2c_set_bus_num(bus_num);
|
||||
|
||||
for (i = 0; i < MAX_I2C_RETRY; ++i) {
|
||||
if (!i2c_read(I2C_ADDRESS, reg, 1, &data, 1)) {
|
||||
if (!i2c_read(tps6586x_dev, reg, &data, 1)) {
|
||||
retval = (int)data;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -53,7 +47,6 @@ static int tps6586x_read(int reg)
|
|||
}
|
||||
|
||||
exit:
|
||||
i2c_set_bus_num(old_bus_num);
|
||||
debug("pmu_read %x=%x\n", reg, retval);
|
||||
if (retval < 0)
|
||||
debug("%s: failed to read register %#x: %d\n", __func__, reg,
|
||||
|
@ -65,13 +58,9 @@ static int tps6586x_write(int reg, uchar *data, uint len)
|
|||
{
|
||||
int i;
|
||||
int retval = -1;
|
||||
int old_bus_num;
|
||||
|
||||
old_bus_num = i2c_get_bus_num();
|
||||
i2c_set_bus_num(bus_num);
|
||||
|
||||
for (i = 0; i < MAX_I2C_RETRY; ++i) {
|
||||
if (!i2c_write(I2C_ADDRESS, reg, 1, data, len)) {
|
||||
if (!i2c_write(tps6586x_dev, reg, data, len)) {
|
||||
retval = 0;
|
||||
goto exit;
|
||||
}
|
||||
|
@ -81,7 +70,6 @@ static int tps6586x_write(int reg, uchar *data, uint len)
|
|||
}
|
||||
|
||||
exit:
|
||||
i2c_set_bus_num(old_bus_num);
|
||||
debug("pmu_write %x=%x: ", reg, retval);
|
||||
for (i = 0; i < len; i++)
|
||||
debug("%x ", data[i]);
|
||||
|
@ -163,7 +151,7 @@ int tps6586x_set_pwm_mode(int mask)
|
|||
uchar val;
|
||||
int ret;
|
||||
|
||||
assert(inited);
|
||||
assert(tps6586x_dev);
|
||||
ret = tps6586x_read(PFM_MODE);
|
||||
if (ret != -1) {
|
||||
val = (uchar)ret;
|
||||
|
@ -184,7 +172,7 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
|
|||
int sm0, sm1;
|
||||
int bad;
|
||||
|
||||
assert(inited);
|
||||
assert(tps6586x_dev);
|
||||
|
||||
/* get current voltage settings */
|
||||
if (read_voltages(&sm0, &sm1)) {
|
||||
|
@ -255,10 +243,9 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
|
|||
return bad ? -1 : 0;
|
||||
}
|
||||
|
||||
int tps6586x_init(int bus)
|
||||
int tps6586x_init(struct udevice *dev)
|
||||
{
|
||||
bus_num = bus;
|
||||
inited = 1;
|
||||
tps6586x_dev = dev;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -348,6 +348,7 @@ U_BOOT_DRIVER(serial_pl01x) = {
|
|||
.probe = pl01x_serial_probe,
|
||||
.ops = &pl01x_serial_ops,
|
||||
.flags = DM_FLAG_PRE_RELOC,
|
||||
.priv_auto_alloc_size = sizeof(struct pl01x_priv),
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -852,30 +852,6 @@ DEFINE_CACHE_ALIGN_BUFFER(u8, control_req, USB_BUFSIZ);
|
|||
DEFINE_CACHE_ALIGN_BUFFER(u8, status_req, STATUS_BYTECOUNT);
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* strlcpy - Copy a %NUL terminated string into a sized buffer
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @size: size of destination buffer
|
||||
*
|
||||
* Compatible with *BSD: the result is always a valid
|
||||
* NUL-terminated string that fits in the buffer (unless,
|
||||
* of course, the buffer size is zero). It does not pad
|
||||
* out the result like strncpy() does.
|
||||
*/
|
||||
size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t ret = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (ret >= size) ? size - 1 : ret;
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*============================================================================*/
|
||||
|
||||
/*
|
||||
|
|
|
@ -91,4 +91,10 @@
|
|||
#undef CONFIG_IMAGE_FORMAT_LEGACY
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
# ifdef CONFIG_SYS_I2C
|
||||
# error "Cannot define CONFIG_SYS_I2C when CONFIG_DM_I2C is used"
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#endif /* __CONFIG_FALLBACKS_H */
|
||||
|
|
|
@ -26,10 +26,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -40,10 +40,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -43,12 +43,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_I2C_MULTI_BUS
|
||||
#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -25,10 +25,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -36,12 +36,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_I2C_MULTI_BUS
|
||||
#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -25,12 +25,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_I2C_MULTI_BUS
|
||||
#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
74
include/configs/nyan-big.h
Normal file
74
include/configs/nyan-big.h
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* (C) Copyright 2014
|
||||
* NVIDIA Corporation <www.nvidia.com>
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __CONFIG_H
|
||||
#define __CONFIG_H
|
||||
|
||||
#include <linux/sizes.h>
|
||||
|
||||
#include "tegra124-common.h"
|
||||
|
||||
/* High-level configuration options */
|
||||
#define V_PROMPT "Tegra124 (Nyan-big) # "
|
||||
#define CONFIG_TEGRA_BOARD_STRING "Google/NVIDIA Nyan-big"
|
||||
|
||||
/* Board-specific serial config */
|
||||
#define CONFIG_SERIAL_MULTI
|
||||
#define CONFIG_TEGRA_ENABLE_UARTA
|
||||
#define CONFIG_SYS_NS16550_COM1 NV_PA_APB_UARTA_BASE
|
||||
|
||||
#define CONFIG_BOARD_EARLY_INIT_F
|
||||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_CMD_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
#define CONFIG_GENERIC_MMC
|
||||
#define CONFIG_TEGRA_MMC
|
||||
#define CONFIG_CMD_MMC
|
||||
|
||||
/* Environment in eMMC, at the end of 2nd "boot sector" */
|
||||
#define CONFIG_ENV_IS_IN_MMC
|
||||
#define CONFIG_SYS_MMC_ENV_DEV 0
|
||||
#define CONFIG_SYS_MMC_ENV_PART 2
|
||||
#define CONFIG_ENV_OFFSET (-CONFIG_ENV_SIZE)
|
||||
|
||||
/* SPI */
|
||||
#define CONFIG_TEGRA114_SPI /* Compatible w/ Tegra114 SPI */
|
||||
#define CONFIG_TEGRA114_SPI_CTRLS 6
|
||||
#define CONFIG_SPI_FLASH
|
||||
#define CONFIG_SPI_FLASH_WINBOND
|
||||
#define CONFIG_SF_DEFAULT_MODE SPI_MODE_0
|
||||
#define CONFIG_SF_DEFAULT_SPEED 24000000
|
||||
#define CONFIG_CMD_SPI
|
||||
#define CONFIG_CMD_SF
|
||||
#define CONFIG_SPI_FLASH_SIZE (4 << 20)
|
||||
|
||||
/* USB Host support */
|
||||
#define CONFIG_USB_EHCI
|
||||
#define CONFIG_USB_EHCI_TEGRA
|
||||
#define CONFIG_USB_MAX_CONTROLLER_COUNT 2
|
||||
#define CONFIG_USB_STORAGE
|
||||
#define CONFIG_CMD_USB
|
||||
|
||||
/* USB networking support */
|
||||
#define CONFIG_USB_HOST_ETHER
|
||||
#define CONFIG_USB_ETHER_ASIX
|
||||
|
||||
/* General networking support */
|
||||
#define CONFIG_CMD_NET
|
||||
#define CONFIG_CMD_DHCP
|
||||
|
||||
#define CONFIG_FIT
|
||||
#define CONFIG_OF_LIBFDT
|
||||
|
||||
#include "tegra-common-usb-gadget.h"
|
||||
#include "tegra-common-post.h"
|
||||
|
||||
#endif /* __CONFIG_H */
|
|
@ -34,6 +34,7 @@
|
|||
#define CONFIG_DM
|
||||
#define CONFIG_CMD_DM
|
||||
#define CONFIG_DM_GPIO
|
||||
#define CONFIG_DM_SERIAL
|
||||
|
||||
/* Memory layout */
|
||||
#define CONFIG_NR_DRAM_BANKS 1
|
||||
|
@ -51,6 +52,7 @@
|
|||
CONFIG_SYS_SDRAM_SIZE - \
|
||||
GENERATED_GBL_DATA_SIZE)
|
||||
#define CONFIG_SYS_MALLOC_LEN SZ_4M
|
||||
#define CONFIG_SYS_MALLOC_F_LEN (1 << 10)
|
||||
#define CONFIG_SYS_MEMTEST_START 0x00100000
|
||||
#define CONFIG_SYS_MEMTEST_END 0x00200000
|
||||
#define CONFIG_LOADADDR 0x00200000
|
||||
|
@ -92,9 +94,7 @@
|
|||
#endif
|
||||
|
||||
/* Console UART */
|
||||
#define CONFIG_PL011_SERIAL
|
||||
#define CONFIG_PL011_CLOCK 3000000
|
||||
#define CONFIG_PL01x_PORTS { (void *)0x20201000 }
|
||||
#define CONFIG_PL01X_SERIAL
|
||||
#define CONFIG_CONS_INDEX 0
|
||||
#define CONFIG_BAUDRATE 115200
|
||||
|
||||
|
|
|
@ -112,6 +112,12 @@
|
|||
#define CONFIG_SPI_FLASH_STMICRO
|
||||
#define CONFIG_SPI_FLASH_WINBOND
|
||||
|
||||
#define CONFIG_DM_I2C
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C_SANDBOX
|
||||
#define CONFIG_I2C_EDID
|
||||
#define CONFIG_I2C_EEPROM
|
||||
|
||||
/* Memory things - we don't really want a memory test */
|
||||
#define CONFIG_SYS_LOAD_ADDR 0x00000000
|
||||
#define CONFIG_SYS_MEMTEST_START 0x00100000
|
||||
|
|
|
@ -37,10 +37,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -23,12 +23,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_I2C_MULTI_BUS
|
||||
#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#endif
|
||||
#define CONFIG_DM_SPI
|
||||
#define CONFIG_DM_SPI_FLASH
|
||||
#define CONFIG_DM_I2C
|
||||
|
||||
#define CONFIG_SYS_TIMER_RATE 1000000
|
||||
#define CONFIG_SYS_TIMER_COUNTER NV_PA_TMRUS_BASE
|
||||
|
|
|
@ -76,9 +76,6 @@
|
|||
#define CONFIG_SYS_SPL_MALLOC_START 0x80090000
|
||||
#define CONFIG_SPL_STACK 0x800ffffc
|
||||
|
||||
/* Total I2C ports on Tegra114 */
|
||||
#define TEGRA_I2C_NUM_CONTROLLERS 5
|
||||
|
||||
/* For USB EHCI controller */
|
||||
#define CONFIG_EHCI_IS_TDI
|
||||
#define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
|
||||
|
|
|
@ -68,9 +68,6 @@
|
|||
#define CONFIG_SYS_SPL_MALLOC_START 0x80090000
|
||||
#define CONFIG_SPL_STACK 0x800ffffc
|
||||
|
||||
/* Total I2C ports on Tegra124 */
|
||||
#define TEGRA_I2C_NUM_CONTROLLERS 5
|
||||
|
||||
/* For USB EHCI controller */
|
||||
#define CONFIG_EHCI_IS_TDI
|
||||
#define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
|
||||
|
|
|
@ -97,9 +97,6 @@
|
|||
#define CONFIG_EHCI_IS_TDI
|
||||
#define CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS 1
|
||||
|
||||
/* Total I2C ports on Tegra20 */
|
||||
#define TEGRA_I2C_NUM_CONTROLLERS 4
|
||||
|
||||
#define CONFIG_SYS_NAND_SELF_INIT
|
||||
#define CONFIG_SYS_NAND_ONFI_DETECTION
|
||||
|
||||
|
|
|
@ -73,9 +73,6 @@
|
|||
#define CONFIG_SYS_SPL_MALLOC_START 0x80090000
|
||||
#define CONFIG_SPL_STACK 0x800ffffc
|
||||
|
||||
/* Total I2C ports on Tegra30 */
|
||||
#define TEGRA_I2C_NUM_CONTROLLERS 5
|
||||
|
||||
/* For USB EHCI controller */
|
||||
#define CONFIG_EHCI_IS_TDI
|
||||
#define CONFIG_USB_EHCI_TXFIFO_THRESH 0x10
|
||||
|
|
|
@ -34,10 +34,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -25,12 +25,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_I2C_MULTI_BUS
|
||||
#define CONFIG_SYS_MAX_I2C_BUS TEGRA_I2C_NUM_CONTROLLERS
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -26,10 +26,7 @@
|
|||
|
||||
/* I2C */
|
||||
#define CONFIG_SYS_I2C_TEGRA
|
||||
#define CONFIG_SYS_I2C_INIT_BOARD
|
||||
#define CONFIG_SYS_I2C_SPEED 100000
|
||||
#define CONFIG_CMD_I2C
|
||||
#define CONFIG_SYS_I2C
|
||||
|
||||
/* SD/MMC */
|
||||
#define CONFIG_MMC
|
||||
|
|
|
@ -19,6 +19,7 @@ enum uclass_id {
|
|||
UCLASS_TEST_FDT,
|
||||
UCLASS_TEST_BUS,
|
||||
UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
|
||||
UCLASS_I2C_EMUL, /* sandbox I2C device emulator */
|
||||
UCLASS_SIMPLE_BUS,
|
||||
|
||||
/* U-Boot uclasses start here */
|
||||
|
@ -29,6 +30,9 @@ enum uclass_id {
|
|||
UCLASS_SPI_FLASH, /* SPI flash */
|
||||
UCLASS_CROS_EC, /* Chrome OS EC */
|
||||
UCLASS_THERMAL, /* Thermal sensor */
|
||||
UCLASS_I2C, /* I2C bus */
|
||||
UCLASS_I2C_GENERIC, /* Generic I2C device */
|
||||
UCLASS_I2C_EEPROM, /* I2C EEPROM device */
|
||||
|
||||
UCLASS_COUNT,
|
||||
UCLASS_INVALID = -1,
|
||||
|
|
|
@ -89,6 +89,18 @@ void ut_failf(struct dm_test_state *dms, const char *fname, int line,
|
|||
} \
|
||||
}
|
||||
|
||||
/* Assert that a pointer is not NULL */
|
||||
#define ut_assertnonnull(expr) { \
|
||||
const void *val = (expr); \
|
||||
\
|
||||
if (val == NULL) { \
|
||||
ut_failf(dms, __FILE__, __LINE__, __func__, \
|
||||
#expr " = NULL", \
|
||||
"Expected non-null, got NULL"); \
|
||||
return -1; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* Assert that an operation succeeds (returns 0) */
|
||||
#define ut_assertok(cond) ut_asserteq(0, cond)
|
||||
|
||||
|
|
45
include/dt-bindings/pinctrl/pinctrl-tegra.h
Normal file
45
include/dt-bindings/pinctrl/pinctrl-tegra.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/*
|
||||
* This header provides constants for Tegra pinctrl bindings.
|
||||
*
|
||||
* Copyright (c) 2013, NVIDIA CORPORATION. All rights reserved.
|
||||
*
|
||||
* Author: Laxman Dewangan <ldewangan@nvidia.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms and conditions of the GNU General Public License,
|
||||
* version 2, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope 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.
|
||||
*/
|
||||
|
||||
#ifndef _DT_BINDINGS_PINCTRL_TEGRA_H
|
||||
#define _DT_BINDINGS_PINCTRL_TEGRA_H
|
||||
|
||||
/*
|
||||
* Enable/disable for diffeent dt properties. This is applicable for
|
||||
* properties nvidia,enable-input, nvidia,tristate, nvidia,open-drain,
|
||||
* nvidia,lock, nvidia,rcv-sel, nvidia,high-speed-mode, nvidia,schmitt.
|
||||
*/
|
||||
#define TEGRA_PIN_DISABLE 0
|
||||
#define TEGRA_PIN_ENABLE 1
|
||||
|
||||
#define TEGRA_PIN_PULL_NONE 0
|
||||
#define TEGRA_PIN_PULL_DOWN 1
|
||||
#define TEGRA_PIN_PULL_UP 2
|
||||
|
||||
/* Low power mode driver */
|
||||
#define TEGRA_PIN_LP_DRIVE_DIV_8 0
|
||||
#define TEGRA_PIN_LP_DRIVE_DIV_4 1
|
||||
#define TEGRA_PIN_LP_DRIVE_DIV_2 2
|
||||
#define TEGRA_PIN_LP_DRIVE_DIV_1 3
|
||||
|
||||
/* Rising/Falling slew rate */
|
||||
#define TEGRA_PIN_SLEW_RATE_FASTEST 0
|
||||
#define TEGRA_PIN_SLEW_RATE_FAST 1
|
||||
#define TEGRA_PIN_SLEW_RATE_SLOW 2
|
||||
#define TEGRA_PIN_SLEW_RATE_SLOWEST 3
|
||||
|
||||
#endif
|
|
@ -6,4 +6,7 @@ extern int errno;
|
|||
|
||||
#define __set_errno(val) do { errno = val; } while (0)
|
||||
|
||||
#ifdef CONFIG_ERRNO_STR
|
||||
const char *errno_str(int errno);
|
||||
#endif
|
||||
#endif /* _ERRNO_H */
|
||||
|
|
352
include/i2c.h
352
include/i2c.h
|
@ -17,6 +17,355 @@
|
|||
#ifndef _I2C_H_
|
||||
#define _I2C_H_
|
||||
|
||||
/*
|
||||
* For now there are essentially two parts to this file - driver model
|
||||
* here at the top, and the older code below (with CONFIG_SYS_I2C being
|
||||
* most recent). The plan is to migrate everything to driver model.
|
||||
* The driver model structures and API are separate as they are different
|
||||
* enough as to be incompatible for compilation purposes.
|
||||
*/
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
|
||||
enum dm_i2c_chip_flags {
|
||||
DM_I2C_CHIP_10BIT = 1 << 0, /* Use 10-bit addressing */
|
||||
DM_I2C_CHIP_RD_ADDRESS = 1 << 1, /* Send address for each read byte */
|
||||
DM_I2C_CHIP_WR_ADDRESS = 1 << 2, /* Send address for each write byte */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_i2c_chip - information about an i2c chip
|
||||
*
|
||||
* An I2C chip is a device on the I2C bus. It sits at a particular address
|
||||
* and normally supports 7-bit or 10-bit addressing.
|
||||
*
|
||||
* To obtain this structure, use dev_get_parentdata(dev) where dev is the
|
||||
* chip to examine.
|
||||
*
|
||||
* @chip_addr: Chip address on bus
|
||||
* @offset_len: Length of offset in bytes. A single byte offset can
|
||||
* represent up to 256 bytes. A value larger than 1 may be
|
||||
* needed for larger devices.
|
||||
* @flags: Flags for this chip (dm_i2c_chip_flags)
|
||||
* @emul: Emulator for this chip address (only used for emulation)
|
||||
*/
|
||||
struct dm_i2c_chip {
|
||||
uint chip_addr;
|
||||
uint offset_len;
|
||||
uint flags;
|
||||
#ifdef CONFIG_SANDBOX
|
||||
struct udevice *emul;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_i2c_bus- information about an i2c bus
|
||||
*
|
||||
* An I2C bus contains 0 or more chips on it, each at its own address. The
|
||||
* bus can operate at different speeds (measured in Hz, typically 100KHz
|
||||
* or 400KHz).
|
||||
*
|
||||
* To obtain this structure, use bus->uclass_priv where bus is the I2C
|
||||
* bus udevice.
|
||||
*
|
||||
* @speed_hz: Bus speed in hertz (typically 100000)
|
||||
*/
|
||||
struct dm_i2c_bus {
|
||||
int speed_hz;
|
||||
};
|
||||
|
||||
/**
|
||||
* i2c_read() - read bytes from an I2C chip
|
||||
*
|
||||
* To obtain an I2C device (called a 'chip') given the I2C bus address you
|
||||
* can use i2c_get_chip(). To obtain a bus by bus number use
|
||||
* uclass_get_device_by_seq(UCLASS_I2C, <bus number>).
|
||||
*
|
||||
* To set the address length of a devce use i2c_set_addr_len(). It
|
||||
* defaults to 1.
|
||||
*
|
||||
* @dev: Chip to read from
|
||||
* @offset: Offset within chip to start reading
|
||||
* @buffer: Place to put data
|
||||
* @len: Number of bytes to read
|
||||
*
|
||||
* @return 0 on success, -ve on failure
|
||||
*/
|
||||
int i2c_read(struct udevice *dev, uint offset, uint8_t *buffer,
|
||||
int len);
|
||||
|
||||
/**
|
||||
* i2c_write() - write bytes to an I2C chip
|
||||
*
|
||||
* See notes for i2c_read() above.
|
||||
*
|
||||
* @dev: Chip to write to
|
||||
* @offset: Offset within chip to start writing
|
||||
* @buffer: Buffer containing data to write
|
||||
* @len: Number of bytes to write
|
||||
*
|
||||
* @return 0 on success, -ve on failure
|
||||
*/
|
||||
int i2c_write(struct udevice *dev, uint offset, const uint8_t *buffer,
|
||||
int len);
|
||||
|
||||
/**
|
||||
* i2c_probe() - probe a particular chip address
|
||||
*
|
||||
* This can be useful to check for the existence of a chip on the bus.
|
||||
* It is typically implemented by writing the chip address to the bus
|
||||
* and checking that the chip replies with an ACK.
|
||||
*
|
||||
* @bus: Bus to probe
|
||||
* @chip_addr: 7-bit address to probe (10-bit and others are not supported)
|
||||
* @chip_flags: Flags for the probe (see enum dm_i2c_chip_flags)
|
||||
* @devp: Returns the device found, or NULL if none
|
||||
* @return 0 if a chip was found at that address, -ve if not
|
||||
*/
|
||||
int i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
|
||||
struct udevice **devp);
|
||||
|
||||
/**
|
||||
* i2c_set_bus_speed() - set the speed of a bus
|
||||
*
|
||||
* @bus: Bus to adjust
|
||||
* @speed: Requested speed in Hz
|
||||
* @return 0 if OK, -EINVAL for invalid values
|
||||
*/
|
||||
int i2c_set_bus_speed(struct udevice *bus, unsigned int speed);
|
||||
|
||||
/**
|
||||
* i2c_get_bus_speed() - get the speed of a bus
|
||||
*
|
||||
* @bus: Bus to check
|
||||
* @return speed of selected I2C bus in Hz, -ve on error
|
||||
*/
|
||||
int i2c_get_bus_speed(struct udevice *bus);
|
||||
|
||||
/**
|
||||
* i2c_set_chip_flags() - set flags for a chip
|
||||
*
|
||||
* Typically addresses are 7 bits, but for 10-bit addresses you should set
|
||||
* flags to DM_I2C_CHIP_10BIT. All accesses will then use 10-bit addressing.
|
||||
*
|
||||
* @dev: Chip to adjust
|
||||
* @flags: New flags
|
||||
* @return 0 if OK, -EINVAL if value is unsupported, other -ve value on error
|
||||
*/
|
||||
int i2c_set_chip_flags(struct udevice *dev, uint flags);
|
||||
|
||||
/**
|
||||
* i2c_get_chip_flags() - get flags for a chip
|
||||
*
|
||||
* @dev: Chip to check
|
||||
* @flagsp: Place to put flags
|
||||
* @return 0 if OK, other -ve value on error
|
||||
*/
|
||||
int i2c_get_chip_flags(struct udevice *dev, uint *flagsp);
|
||||
|
||||
/**
|
||||
* i2c_set_offset_len() - set the offset length for a chip
|
||||
*
|
||||
* The offset used to access a chip may be up to 4 bytes long. Typically it
|
||||
* is only 1 byte, which is enough for chips with 256 bytes of memory or
|
||||
* registers. The default value is 1, but you can call this function to
|
||||
* change it.
|
||||
*
|
||||
* @offset_len: New offset length value (typically 1 or 2)
|
||||
*/
|
||||
|
||||
int i2c_set_chip_offset_len(struct udevice *dev, uint offset_len);
|
||||
/**
|
||||
* i2c_deblock() - recover a bus that is in an unknown state
|
||||
*
|
||||
* See the deblock() method in 'struct dm_i2c_ops' for full information
|
||||
*
|
||||
* @bus: Bus to recover
|
||||
* @return 0 if OK, -ve on error
|
||||
*/
|
||||
int i2c_deblock(struct udevice *bus);
|
||||
|
||||
/*
|
||||
* Not all of these flags are implemented in the U-Boot API
|
||||
*/
|
||||
enum dm_i2c_msg_flags {
|
||||
I2C_M_TEN = 0x0010, /* ten-bit chip address */
|
||||
I2C_M_RD = 0x0001, /* read data, from slave to master */
|
||||
I2C_M_STOP = 0x8000, /* send stop after this message */
|
||||
I2C_M_NOSTART = 0x4000, /* no start before this message */
|
||||
I2C_M_REV_DIR_ADDR = 0x2000, /* invert polarity of R/W bit */
|
||||
I2C_M_IGNORE_NAK = 0x1000, /* continue after NAK */
|
||||
I2C_M_NO_RD_ACK = 0x0800, /* skip the Ack bit on reads */
|
||||
I2C_M_RECV_LEN = 0x0400, /* length is first received byte */
|
||||
};
|
||||
|
||||
/**
|
||||
* struct i2c_msg - an I2C message
|
||||
*
|
||||
* @addr: Slave address
|
||||
* @flags: Flags (see enum dm_i2c_msg_flags)
|
||||
* @len: Length of buffer in bytes, may be 0 for a probe
|
||||
* @buf: Buffer to send/receive, or NULL if no data
|
||||
*/
|
||||
struct i2c_msg {
|
||||
uint addr;
|
||||
uint flags;
|
||||
uint len;
|
||||
u8 *buf;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct i2c_msg_list - a list of I2C messages
|
||||
*
|
||||
* This is called i2c_rdwr_ioctl_data in Linux but the name does not seem
|
||||
* appropriate in U-Boot.
|
||||
*
|
||||
* @msg: Pointer to i2c_msg array
|
||||
* @nmsgs: Number of elements in the array
|
||||
*/
|
||||
struct i2c_msg_list {
|
||||
struct i2c_msg *msgs;
|
||||
uint nmsgs;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct dm_i2c_ops - driver operations for I2C uclass
|
||||
*
|
||||
* Drivers should support these operations unless otherwise noted. These
|
||||
* operations are intended to be used by uclass code, not directly from
|
||||
* other code.
|
||||
*/
|
||||
struct dm_i2c_ops {
|
||||
/**
|
||||
* xfer() - transfer a list of I2C messages
|
||||
*
|
||||
* @bus: Bus to read from
|
||||
* @msg: List of messages to transfer
|
||||
* @nmsgs: Number of messages in the list
|
||||
* @return 0 if OK, -EREMOTEIO if the slave did not ACK a byte,
|
||||
* -ECOMM if the speed cannot be supported, -EPROTO if the chip
|
||||
* flags cannot be supported, other -ve value on some other error
|
||||
*/
|
||||
int (*xfer)(struct udevice *bus, struct i2c_msg *msg, int nmsgs);
|
||||
|
||||
/**
|
||||
* probe_chip() - probe for the presense of a chip address
|
||||
*
|
||||
* This function is optional. If omitted, the uclass will send a zero
|
||||
* length message instead.
|
||||
*
|
||||
* @bus: Bus to probe
|
||||
* @chip_addr: Chip address to probe
|
||||
* @chip_flags: Probe flags (enum dm_i2c_chip_flags)
|
||||
* @return 0 if chip was found, -EREMOTEIO if not, -ENOSYS to fall back
|
||||
* to default probem other -ve value on error
|
||||
*/
|
||||
int (*probe_chip)(struct udevice *bus, uint chip_addr, uint chip_flags);
|
||||
|
||||
/**
|
||||
* set_bus_speed() - set the speed of a bus (optional)
|
||||
*
|
||||
* The bus speed value will be updated by the uclass if this function
|
||||
* does not return an error. This method is optional - if it is not
|
||||
* provided then the driver can read the speed from
|
||||
* bus->uclass_priv->speed_hz
|
||||
*
|
||||
* @bus: Bus to adjust
|
||||
* @speed: Requested speed in Hz
|
||||
* @return 0 if OK, -EINVAL for invalid values
|
||||
*/
|
||||
int (*set_bus_speed)(struct udevice *bus, unsigned int speed);
|
||||
|
||||
/**
|
||||
* get_bus_speed() - get the speed of a bus (optional)
|
||||
*
|
||||
* Normally this can be provided by the uclass, but if you want your
|
||||
* driver to check the bus speed by looking at the hardware, you can
|
||||
* implement that here. This method is optional. This method would
|
||||
* normally be expected to return bus->uclass_priv->speed_hz.
|
||||
*
|
||||
* @bus: Bus to check
|
||||
* @return speed of selected I2C bus in Hz, -ve on error
|
||||
*/
|
||||
int (*get_bus_speed)(struct udevice *bus);
|
||||
|
||||
/**
|
||||
* set_flags() - set the flags for a chip (optional)
|
||||
*
|
||||
* This is generally implemented by the uclass, but drivers can
|
||||
* check the value to ensure that unsupported options are not used.
|
||||
* This method is optional. If provided, this method will always be
|
||||
* called when the flags change.
|
||||
*
|
||||
* @dev: Chip to adjust
|
||||
* @flags: New flags value
|
||||
* @return 0 if OK, -EINVAL if value is unsupported
|
||||
*/
|
||||
int (*set_flags)(struct udevice *dev, uint flags);
|
||||
|
||||
/**
|
||||
* deblock() - recover a bus that is in an unknown state
|
||||
*
|
||||
* I2C is a synchronous protocol and resets of the processor in the
|
||||
* middle of an access can block the I2C Bus until a powerdown of
|
||||
* the full unit is done. This is because slaves can be stuck
|
||||
* waiting for addition bus transitions for a transaction that will
|
||||
* never complete. Resetting the I2C master does not help. The only
|
||||
* way is to force the bus through a series of transitions to make
|
||||
* sure that all slaves are done with the transaction. This method
|
||||
* performs this 'deblocking' if support by the driver.
|
||||
*
|
||||
* This method is optional.
|
||||
*/
|
||||
int (*deblock)(struct udevice *bus);
|
||||
};
|
||||
|
||||
#define i2c_get_ops(dev) ((struct dm_i2c_ops *)(dev)->driver->ops)
|
||||
|
||||
/**
|
||||
* i2c_get_chip() - get a device to use to access a chip on a bus
|
||||
*
|
||||
* This returns the device for the given chip address. The device can then
|
||||
* be used with calls to i2c_read(), i2c_write(), i2c_probe(), etc.
|
||||
*
|
||||
* @bus: Bus to examine
|
||||
* @chip_addr: Chip address for the new device
|
||||
* @devp: Returns pointer to new device if found or -ENODEV if not
|
||||
* found
|
||||
*/
|
||||
int i2c_get_chip(struct udevice *bus, uint chip_addr, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* i2c_get_chip() - get a device to use to access a chip on a bus number
|
||||
*
|
||||
* This returns the device for the given chip address on a particular bus
|
||||
* number.
|
||||
*
|
||||
* @busnum: Bus number to examine
|
||||
* @chip_addr: Chip address for the new device
|
||||
* @devp: Returns pointer to new device if found or -ENODEV if not
|
||||
* found
|
||||
*/
|
||||
int i2c_get_chip_for_busnum(int busnum, int chip_addr, struct udevice **devp);
|
||||
|
||||
/**
|
||||
* i2c_chip_ofdata_to_platdata() - Decode standard I2C platform data
|
||||
*
|
||||
* This decodes the chip address from a device tree node and puts it into
|
||||
* its dm_i2c_chip structure. This should be called in your driver's
|
||||
* ofdata_to_platdata() method.
|
||||
*
|
||||
* @blob: Device tree blob
|
||||
* @node: Node offset to read from
|
||||
* @spi: Place to put the decoded information
|
||||
*/
|
||||
int i2c_chip_ofdata_to_platdata(const void *blob, int node,
|
||||
struct dm_i2c_chip *chip);
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_DM_I2C
|
||||
|
||||
/*
|
||||
* WARNING WARNING WARNING WARNING WARNING WARNING WARNING WARNING
|
||||
*
|
||||
|
@ -451,4 +800,7 @@ int i2c_get_bus_num_fdt(int node);
|
|||
* @return 0 if port was reset, -1 if not found
|
||||
*/
|
||||
int i2c_reset_port_fdt(const void *blob, int node);
|
||||
|
||||
#endif /* !CONFIG_DM_I2C */
|
||||
|
||||
#endif /* _I2C_H_ */
|
||||
|
|
19
include/i2c_eeprom.h
Normal file
19
include/i2c_eeprom.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* Copyright (c) 2014 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
|
||||
#ifndef __I2C_EEPROM
|
||||
#define __I2C_EEPROM
|
||||
|
||||
struct i2c_eeprom_ops {
|
||||
int (*read)(struct udevice *dev, int offset, uint8_t *buf, int size);
|
||||
int (*write)(struct udevice *dev, int offset, const uint8_t *buf,
|
||||
int size);
|
||||
};
|
||||
|
||||
struct i2c_eeprom {
|
||||
};
|
||||
|
||||
#endif
|
|
@ -30,6 +30,9 @@ extern char * strcpy(char *,const char *);
|
|||
#ifndef __HAVE_ARCH_STRNCPY
|
||||
extern char * strncpy(char *,const char *, __kernel_size_t);
|
||||
#endif
|
||||
#ifndef __HAVE_ARCH_STRLCPY
|
||||
size_t strlcpy(char *, const char *, size_t);
|
||||
#endif
|
||||
#ifndef __HAVE_ARCH_STRCAT
|
||||
extern char * strcat(char *, const char *);
|
||||
#endif
|
||||
|
|
|
@ -44,9 +44,9 @@ int tps6586x_adjust_sm0_sm1(int sm0_target, int sm1_target, int step, int rate,
|
|||
* Set up the TPS6586X I2C bus number. This will be used for all operations
|
||||
* on the device. This function must be called before using other functions.
|
||||
*
|
||||
* @param bus I2C bus number containing the TPS6586X chip
|
||||
* @param bus I2C bus containing the TPS6586X chip
|
||||
* @return 0 (always succeeds)
|
||||
*/
|
||||
int tps6586x_init(int bus);
|
||||
int tps6586x_init(struct udevice *bus);
|
||||
|
||||
#endif /* _TPS6586X_H_ */
|
||||
|
|
|
@ -51,6 +51,7 @@ endif
|
|||
obj-$(CONFIG_ADDR_MAP) += addr_map.o
|
||||
obj-y += hashtable.o
|
||||
obj-y += errno.o
|
||||
obj-$(CONFIG_ERRNO_STR) += errno_str.o
|
||||
obj-y += display_options.o
|
||||
obj-$(CONFIG_BCH) += bch.o
|
||||
obj-y += crc32.o
|
||||
|
|
147
lib/errno_str.c
Normal file
147
lib/errno_str.c
Normal file
|
@ -0,0 +1,147 @@
|
|||
/*
|
||||
* Copyright (C) 2014 Samsung Electronics
|
||||
* Przemyslaw Marczak <p.marczak@samsung.com>
|
||||
*
|
||||
* SDPX-License-Identifier: GPL-2.0+
|
||||
*/
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
|
||||
#define ERRNO_MSG(errno, msg) msg
|
||||
#define SAME_AS(x) (const char *)&errno_message[x]
|
||||
|
||||
static const char * const errno_message[] = {
|
||||
ERRNO_MSG(0, "Success"),
|
||||
ERRNO_MSG(EPERM, "Operation not permitted"),
|
||||
ERRNO_MSG(ENOEN, "No such file or directory"),
|
||||
ERRNO_MSG(ESRCH, "No such process"),
|
||||
ERRNO_MSG(EINTR, "Interrupted system call"),
|
||||
ERRNO_MSG(EIO, "I/O error"),
|
||||
ERRNO_MSG(ENXIO, "No such device or address"),
|
||||
ERRNO_MSG(E2BIG, "Argument list too long"),
|
||||
ERRNO_MSG(ENOEXEC, "Exec format error"),
|
||||
ERRNO_MSG(EBADF, "Bad file number"),
|
||||
ERRNO_MSG(ECHILD, "No child processes"),
|
||||
ERRNO_MSG(EAGAIN, "Try again"),
|
||||
ERRNO_MSG(ENOMEM, "Out of memory"),
|
||||
ERRNO_MSG(EACCES, "Permission denied"),
|
||||
ERRNO_MSG(EFAULT, "Bad address"),
|
||||
ERRNO_MSG(ENOTBL, "Block device required"),
|
||||
ERRNO_MSG(EBUSY, "Device or resource busy"),
|
||||
ERRNO_MSG(EEXIST, "File exists"),
|
||||
ERRNO_MSG(EXDEV, "Cross-device link"),
|
||||
ERRNO_MSG(ENODEV, "No such device"),
|
||||
ERRNO_MSG(ENOTDIR, "Not a directory"),
|
||||
ERRNO_MSG(EISDIR, "Is a directory"),
|
||||
ERRNO_MSG(EINVAL, "Invalid argument"),
|
||||
ERRNO_MSG(ENFILE, "File table overflow"),
|
||||
ERRNO_MSG(EMFILE, "Too many open files"),
|
||||
ERRNO_MSG(ENOTTY, "Not a typewriter"),
|
||||
ERRNO_MSG(ETXTBSY, "Text file busy"),
|
||||
ERRNO_MSG(EFBIG, "File too large"),
|
||||
ERRNO_MSG(ENOSPC, "No space left on device"),
|
||||
ERRNO_MSG(ESPIPE, "Illegal seek"),
|
||||
ERRNO_MSG(EROFS, "Read-only file system"),
|
||||
ERRNO_MSG(EMLINK, "Too many links"),
|
||||
ERRNO_MSG(EPIPE, "Broken pipe"),
|
||||
ERRNO_MSG(EDOM, "Math argument out of domain of func"),
|
||||
ERRNO_MSG(ERANGE, "Math result not representable"),
|
||||
ERRNO_MSG(EDEADLK, "Resource deadlock would occur"),
|
||||
ERRNO_MSG(ENAMETOOLONG, "File name too long"),
|
||||
ERRNO_MSG(ENOLCK, "No record locks available"),
|
||||
ERRNO_MSG(ENOSYS, "Function not implemented"),
|
||||
ERRNO_MSG(ENOTEMPTY, "Directory not empty"),
|
||||
ERRNO_MSG(ELOOP, "Too many symbolic links encountered"),
|
||||
ERRNO_MSG(EWOULDBLOCK, SAME_AS(EAGAIN)),
|
||||
ERRNO_MSG(ENOMSG, "No message of desired type"),
|
||||
ERRNO_MSG(EIDRM, "Identifier removed"),
|
||||
ERRNO_MSG(ECHRNG, "Channel number out of range"),
|
||||
ERRNO_MSG(EL2NSYNC, "Level 2 not synchronized"),
|
||||
ERRNO_MSG(EL3HLT, "Level 3 halted"),
|
||||
ERRNO_MSG(EL3RST, "Level 3 reset"),
|
||||
ERRNO_MSG(ELNRNG, "Link number out of range"),
|
||||
ERRNO_MSG(EUNATCH, "Protocol driver not attached"),
|
||||
ERRNO_MSG(ENOCSI, "No CSI structure available"),
|
||||
ERRNO_MSG(EL2HLT, "Level 2 halted"),
|
||||
ERRNO_MSG(EBADE, "Invalid exchange"),
|
||||
ERRNO_MSG(EBADR, "Invalid request descriptor"),
|
||||
ERRNO_MSG(EXFULL, "Exchange full"),
|
||||
ERRNO_MSG(ENOANO, "No anode"),
|
||||
ERRNO_MSG(EBADRQC, "Invalid request code"),
|
||||
ERRNO_MSG(EBADSLT, "Invalid slot"),
|
||||
ERRNO_MSG(EDEADLOCK, SAME_AS(EDEADLK)),
|
||||
ERRNO_MSG(EBFONT, "Bad font file format"),
|
||||
ERRNO_MSG(ENOSTR, "Device not a stream"),
|
||||
ERRNO_MSG(ENODATA, "No data available"),
|
||||
ERRNO_MSG(ETIME, "Timer expired"),
|
||||
ERRNO_MSG(ENOSR, "Out of streams resources"),
|
||||
ERRNO_MSG(ENONET, "Machine is not on the network"),
|
||||
ERRNO_MSG(ENOPKG, "Package not installed"),
|
||||
ERRNO_MSG(EREMOTE, "Object is remote"),
|
||||
ERRNO_MSG(ENOLINK, "Link has been severed"),
|
||||
ERRNO_MSG(EADV, "Advertise error"),
|
||||
ERRNO_MSG(ESRMNT, "Srmount error"),
|
||||
ERRNO_MSG(ECOMM, "Communication error on send"),
|
||||
ERRNO_MSG(EPROTO, "Protocol error"),
|
||||
ERRNO_MSG(EMULTIHOP, "Multihop attempted"),
|
||||
ERRNO_MSG(EDOTDOT, "RFS specific error"),
|
||||
ERRNO_MSG(EBADMSG, "Not a data message"),
|
||||
ERRNO_MSG(EOVERFLOW, "Value too large for defined data type"),
|
||||
ERRNO_MSG(ENOTUNIQ, "Name not unique on network"),
|
||||
ERRNO_MSG(EBADFD, "File descriptor in bad state"),
|
||||
ERRNO_MSG(EREMCHG, "Remote address changed"),
|
||||
ERRNO_MSG(ELIBACC, "Can not access a needed shared library"),
|
||||
ERRNO_MSG(ELIBBAD, "Accessing a corrupted shared library"),
|
||||
ERRNO_MSG(ELIBSCN, ".lib section in a.out corrupted"),
|
||||
ERRNO_MSG(ELIBMAX, "Attempting to link in too many shared libraries"),
|
||||
ERRNO_MSG(ELIBEXEC, "Cannot exec a shared library directly"),
|
||||
ERRNO_MSG(EILSEQ, "Illegal byte sequence"),
|
||||
ERRNO_MSG(ERESTART, "Interrupted system call should be restarted"),
|
||||
ERRNO_MSG(ESTRPIPE, "Streams pipe error"),
|
||||
ERRNO_MSG(EUSERS, "Too many users"),
|
||||
ERRNO_MSG(ENOTSOCK, "Socket operation on non-socket"),
|
||||
ERRNO_MSG(EDESTADDRREQ, "Destination address required"),
|
||||
ERRNO_MSG(EMSGSIZE, "Message too long"),
|
||||
ERRNO_MSG(EPROTOTYPE, "Protocol wrong type for socket"),
|
||||
ERRNO_MSG(ENOPROTOOPT, "Protocol not available"),
|
||||
ERRNO_MSG(EPROTONOSUPPORT, "Protocol not supported"),
|
||||
ERRNO_MSG(ESOCKTNOSUPPORT, "Socket type not supported"),
|
||||
ERRNO_MSG(EOPNOTSUPP, "Operation not supported on transport endpoint"),
|
||||
ERRNO_MSG(EPFNOSUPPORT, "Protocol family not supported"),
|
||||
ERRNO_MSG(AFNOSUPPORT, "Address family not supported by protocol"),
|
||||
ERRNO_MSG(EADDRINUSE, "Address already in use"),
|
||||
ERRNO_MSG(EADDRNOTAVAIL, "Cannot assign requested address"),
|
||||
ERRNO_MSG(ENETDOWN, "Network is down"),
|
||||
ERRNO_MSG(ENETUNREACH, "Network is unreachable"),
|
||||
ERRNO_MSG(ENETRESET, "Network dropped connection because of reset"),
|
||||
ERRNO_MSG(ECONNABORTED, "Software caused connection abort"),
|
||||
ERRNO_MSG(ECONNRESET, "Connection reset by peer"),
|
||||
ERRNO_MSG(ENOBUFS, "No buffer space available"),
|
||||
ERRNO_MSG(EISCONN, "Transport endpoint is already connected"),
|
||||
ERRNO_MSG(ENOTCONN, "Transport endpoint is not connected"),
|
||||
ERRNO_MSG(ESHUTDOWN, "Cannot send after transport endpoint shutdown"),
|
||||
ERRNO_MSG(ETOOMANYREFS, "Too many references: cannot splice"),
|
||||
ERRNO_MSG(ETIMEDOUT, "Connection timed out"),
|
||||
ERRNO_MSG(ECONNREFUSED, "Connection refused"),
|
||||
ERRNO_MSG(EHOSTDOWN, "Host is down"),
|
||||
ERRNO_MSG(EHOSTUNREACH, "No route to host"),
|
||||
ERRNO_MSG(EALREADY, "Operation already in progress"),
|
||||
ERRNO_MSG(EINPROGRESS, "Operation now in progress"),
|
||||
ERRNO_MSG(ESTALE, "Stale NFS file handle"),
|
||||
ERRNO_MSG(EUCLEAN, "Structure needs cleaning"),
|
||||
ERRNO_MSG(ENOTNAM, "Not a XENIX named type file"),
|
||||
ERRNO_MSG(ENAVAIL, "No XENIX semaphores available"),
|
||||
ERRNO_MSG(EISNAM, "Is a named type file"),
|
||||
ERRNO_MSG(EREMOTEIO, "Remote I/O error"),
|
||||
ERRNO_MSG(EDQUOT, "Quota exceeded"),
|
||||
ERRNO_MSG(ENOMEDIUM, "No medium found"),
|
||||
ERRNO_MSG(EMEDIUMTYPE, "Wrong medium type"),
|
||||
};
|
||||
|
||||
const char *errno_str(int errno)
|
||||
{
|
||||
if (errno >= 0)
|
||||
return errno_message[0];
|
||||
|
||||
return errno_message[abs(errno)];
|
||||
}
|
25
lib/string.c
25
lib/string.c
|
@ -102,6 +102,31 @@ char * strncpy(char * dest,const char *src,size_t count)
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRLCPY
|
||||
/**
|
||||
* strlcpy - Copy a C-string into a sized buffer
|
||||
* @dest: Where to copy the string to
|
||||
* @src: Where to copy the string from
|
||||
* @size: size of destination buffer
|
||||
*
|
||||
* Compatible with *BSD: the result is always a valid
|
||||
* NUL-terminated string that fits in the buffer (unless,
|
||||
* of course, the buffer size is zero). It does not pad
|
||||
* out the result like strncpy() does.
|
||||
*/
|
||||
size_t strlcpy(char *dest, const char *src, size_t size)
|
||||
{
|
||||
size_t ret = strlen(src);
|
||||
|
||||
if (size) {
|
||||
size_t len = (ret >= size) ? size - 1 : ret;
|
||||
memcpy(dest, src, len);
|
||||
dest[len] = '\0';
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRCAT
|
||||
/**
|
||||
* strcat - Append one %NUL-terminated string to another
|
||||
|
|
|
@ -20,4 +20,5 @@ ifneq ($(CONFIG_SANDBOX),)
|
|||
obj-$(CONFIG_DM_GPIO) += gpio.o
|
||||
obj-$(CONFIG_DM_SPI) += spi.o
|
||||
obj-$(CONFIG_DM_SPI_FLASH) += sf.o
|
||||
obj-$(CONFIG_DM_I2C) += i2c.o
|
||||
endif
|
||||
|
|
103
test/dm/cmd_dm.c
103
test/dm/cmd_dm.c
|
@ -16,59 +16,38 @@
|
|||
#include <dm/test.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
|
||||
/**
|
||||
* dm_display_line() - Display information about a single device
|
||||
*
|
||||
* Displays a single line of information with an option prefix
|
||||
*
|
||||
* @dev: Device to display
|
||||
* @buf: Prefix to display at the start of the line
|
||||
*/
|
||||
static void dm_display_line(struct udevice *dev, char *buf)
|
||||
static void show_devices(struct udevice *dev, int depth, int last_flag)
|
||||
{
|
||||
printf("%s- %c %s @ %08lx", buf,
|
||||
dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
|
||||
dev->name, (ulong)map_to_sysmem(dev));
|
||||
if (dev->req_seq != -1)
|
||||
printf(", %d", dev->req_seq);
|
||||
puts("\n");
|
||||
int i, is_last;
|
||||
struct udevice *child;
|
||||
char class_name[12];
|
||||
|
||||
/* print the first 11 characters to not break the tree-format. */
|
||||
strlcpy(class_name, dev->uclass->uc_drv->name, sizeof(class_name));
|
||||
printf(" %-11s [ %c ] ", class_name,
|
||||
dev->flags & DM_FLAG_ACTIVATED ? '+' : ' ');
|
||||
|
||||
for (i = depth; i >= 0; i--) {
|
||||
is_last = (last_flag >> i) & 1;
|
||||
if (i) {
|
||||
if (is_last)
|
||||
printf(" ");
|
||||
else
|
||||
printf("| ");
|
||||
} else {
|
||||
if (is_last)
|
||||
printf("`-- ");
|
||||
else
|
||||
printf("|-- ");
|
||||
}
|
||||
}
|
||||
|
||||
static int display_succ(struct udevice *in, char *buf)
|
||||
{
|
||||
int len;
|
||||
int ip = 0;
|
||||
char local[16];
|
||||
struct udevice *pos, *n, *prev = NULL;
|
||||
printf("%s\n", dev->name);
|
||||
|
||||
dm_display_line(in, buf);
|
||||
|
||||
if (list_empty(&in->child_head))
|
||||
return 0;
|
||||
|
||||
len = strlen(buf);
|
||||
strncpy(local, buf, sizeof(local));
|
||||
snprintf(local + len, 2, "|");
|
||||
if (len && local[len - 1] == '`')
|
||||
local[len - 1] = ' ';
|
||||
|
||||
list_for_each_entry_safe(pos, n, &in->child_head, sibling_node) {
|
||||
if (ip++)
|
||||
display_succ(prev, local);
|
||||
prev = pos;
|
||||
list_for_each_entry(child, &dev->child_head, sibling_node) {
|
||||
is_last = list_is_last(&child->sibling_node, &dev->child_head);
|
||||
show_devices(child, depth + 1, (last_flag << 1) | is_last);
|
||||
}
|
||||
|
||||
snprintf(local + len, 2, "`");
|
||||
display_succ(prev, local);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int dm_dump(struct udevice *dev)
|
||||
{
|
||||
if (!dev)
|
||||
return -EINVAL;
|
||||
return display_succ(dev, "");
|
||||
}
|
||||
|
||||
static int do_dm_dump_all(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
|
@ -77,8 +56,30 @@ static int do_dm_dump_all(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
struct udevice *root;
|
||||
|
||||
root = dm_root();
|
||||
printf("ROOT %08lx\n", (ulong)map_to_sysmem(root));
|
||||
return dm_dump(root);
|
||||
if (root) {
|
||||
printf(" Class Probed Name\n");
|
||||
printf("----------------------------------------\n");
|
||||
show_devices(root, -1, 0);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* dm_display_line() - Display information about a single device
|
||||
*
|
||||
* Displays a single line of information with an option prefix
|
||||
*
|
||||
* @dev: Device to display
|
||||
*/
|
||||
static void dm_display_line(struct udevice *dev)
|
||||
{
|
||||
printf("- %c %s @ %08lx",
|
||||
dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
|
||||
dev->name, (ulong)map_to_sysmem(dev));
|
||||
if (dev->req_seq != -1)
|
||||
printf(", %d", dev->req_seq);
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
|
||||
|
@ -99,7 +100,7 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
|
|||
if (list_empty(&uc->dev_head))
|
||||
continue;
|
||||
list_for_each_entry(dev, &uc->dev_head, uclass_node) {
|
||||
dm_display_line(dev, "");
|
||||
dm_display_line(dev);
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
|
216
test/dm/i2c.c
Normal file
216
test/dm/i2c.c
Normal file
|
@ -0,0 +1,216 @@
|
|||
/*
|
||||
* Copyright (C) 2013 Google, Inc
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Note: Test coverage does not include 10-bit addressing
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <i2c.h>
|
||||
#include <dm/device-internal.h>
|
||||
#include <dm/test.h>
|
||||
#include <dm/uclass-internal.h>
|
||||
#include <dm/ut.h>
|
||||
#include <dm/util.h>
|
||||
#include <asm/state.h>
|
||||
#include <asm/test.h>
|
||||
|
||||
static const int busnum;
|
||||
static const int chip = 0x2c;
|
||||
|
||||
/* Test that we can find buses and chips */
|
||||
static int dm_test_i2c_find(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *bus, *dev;
|
||||
const int no_chip = 0x10;
|
||||
|
||||
ut_asserteq(-ENODEV, uclass_find_device_by_seq(UCLASS_I2C, busnum,
|
||||
false, &bus));
|
||||
|
||||
/*
|
||||
* i2c_post_bind() will bind devices to chip selects. Check this then
|
||||
* remove the emulation and the slave device.
|
||||
*/
|
||||
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
|
||||
ut_assertok(i2c_probe(bus, chip, 0, &dev));
|
||||
ut_asserteq(-ENODEV, i2c_probe(bus, no_chip, 0, &dev));
|
||||
ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_I2C, 1, &bus));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_find, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_i2c_read_write(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *bus, *dev;
|
||||
uint8_t buf[5];
|
||||
|
||||
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
|
||||
ut_assertok(i2c_get_chip(bus, chip, &dev));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
|
||||
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\0AB\0", sizeof(buf)));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_read_write, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_i2c_speed(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *bus, *dev;
|
||||
uint8_t buf[5];
|
||||
|
||||
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
|
||||
ut_assertok(i2c_get_chip(bus, chip, &dev));
|
||||
ut_assertok(i2c_set_bus_speed(bus, 100000));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(i2c_set_bus_speed(bus, 400000));
|
||||
ut_asserteq(400000, i2c_get_bus_speed(bus));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_asserteq(-EINVAL, i2c_write(dev, 0, buf, 5));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_speed, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_i2c_offset_len(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *bus, *dev;
|
||||
uint8_t buf[5];
|
||||
|
||||
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
|
||||
ut_assertok(i2c_get_chip(bus, chip, &dev));
|
||||
ut_assertok(i2c_set_chip_offset_len(dev, 1));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
|
||||
/* This is not supported by the uclass */
|
||||
ut_asserteq(-EINVAL, i2c_set_chip_offset_len(dev, 5));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_offset_len, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_i2c_probe_empty(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *bus, *dev;
|
||||
|
||||
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
|
||||
ut_assertok(i2c_probe(bus, SANDBOX_I2C_TEST_ADDR, 0, &dev));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_probe_empty, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_i2c_bytewise(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *bus, *dev;
|
||||
struct udevice *eeprom;
|
||||
uint8_t buf[5];
|
||||
|
||||
ut_assertok(uclass_get_device_by_seq(UCLASS_I2C, busnum, &bus));
|
||||
ut_assertok(i2c_get_chip(bus, chip, &dev));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
|
||||
|
||||
/* Tell the EEPROM to only read/write one register at a time */
|
||||
ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
|
||||
ut_assertnonnull(eeprom);
|
||||
sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_SINGLE_BYTE);
|
||||
|
||||
/* Now we only get the first byte - the rest will be 0xff */
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
|
||||
|
||||
/* If we do a separate transaction for each byte, it works */
|
||||
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\0\0\0\0", sizeof(buf)));
|
||||
|
||||
/* This will only write A */
|
||||
ut_assertok(i2c_set_chip_flags(dev, 0));
|
||||
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
|
||||
|
||||
/* Check that the B was ignored */
|
||||
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_RD_ADDRESS));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\0A\0\0\0", sizeof(buf)));
|
||||
|
||||
/* Now write it again with the new flags, it should work */
|
||||
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS));
|
||||
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\xff\xff\xff\xff", sizeof(buf)));
|
||||
|
||||
ut_assertok(i2c_set_chip_flags(dev, DM_I2C_CHIP_WR_ADDRESS |
|
||||
DM_I2C_CHIP_RD_ADDRESS));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "\0\0AB\0\0", sizeof(buf)));
|
||||
|
||||
/* Restore defaults */
|
||||
sandbox_i2c_eeprom_set_test_mode(eeprom, SIE_TEST_MODE_NONE);
|
||||
ut_assertok(i2c_set_chip_flags(dev, 0));
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_bytewise, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
||||
|
||||
static int dm_test_i2c_offset(struct dm_test_state *dms)
|
||||
{
|
||||
struct udevice *eeprom;
|
||||
struct udevice *dev;
|
||||
uint8_t buf[5];
|
||||
|
||||
ut_assertok(i2c_get_chip_for_busnum(busnum, chip, &dev));
|
||||
|
||||
/* Do a transfer so we can find the emulator */
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(uclass_first_device(UCLASS_I2C_EMUL, &eeprom));
|
||||
|
||||
/* Offset length 0 */
|
||||
sandbox_i2c_eeprom_set_offset_len(eeprom, 0);
|
||||
ut_assertok(i2c_set_chip_offset_len(dev, 0));
|
||||
ut_assertok(i2c_write(dev, 10 /* ignored */, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "AB\0\0\0\0", sizeof(buf)));
|
||||
|
||||
/* Offset length 1 */
|
||||
sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
|
||||
ut_assertok(i2c_set_chip_offset_len(dev, 1));
|
||||
ut_assertok(i2c_write(dev, 2, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0, buf, 5));
|
||||
ut_assertok(memcmp(buf, "ABAB\0", sizeof(buf)));
|
||||
|
||||
/* Offset length 2 */
|
||||
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
|
||||
ut_assertok(i2c_set_chip_offset_len(dev, 2));
|
||||
ut_assertok(i2c_write(dev, 0x210, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0x210, buf, 5));
|
||||
ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
|
||||
|
||||
/* Offset length 3 */
|
||||
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
|
||||
ut_assertok(i2c_set_chip_offset_len(dev, 2));
|
||||
ut_assertok(i2c_write(dev, 0x410, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0x410, buf, 5));
|
||||
ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
|
||||
|
||||
/* Offset length 4 */
|
||||
sandbox_i2c_eeprom_set_offset_len(eeprom, 2);
|
||||
ut_assertok(i2c_set_chip_offset_len(dev, 2));
|
||||
ut_assertok(i2c_write(dev, 0x420, (uint8_t *)"AB", 2));
|
||||
ut_assertok(i2c_read(dev, 0x420, buf, 5));
|
||||
ut_assertok(memcmp(buf, "AB\0\0\0", sizeof(buf)));
|
||||
|
||||
/* Restore defaults */
|
||||
sandbox_i2c_eeprom_set_offset_len(eeprom, 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
DM_TEST(dm_test_i2c_offset, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
|
|
@ -93,6 +93,23 @@
|
|||
num-gpios = <10>;
|
||||
};
|
||||
|
||||
i2c@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
reg = <0>;
|
||||
compatible = "sandbox,i2c";
|
||||
clock-frequency = <100000>;
|
||||
eeprom@2c {
|
||||
reg = <0x2c>;
|
||||
compatible = "i2c-eeprom";
|
||||
emul {
|
||||
compatible = "sandbox,i2c-eeprom";
|
||||
sandbox,filename = "i2c.bin";
|
||||
sandbox,size = <256>;
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
spi@0 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
|
Loading…
Reference in a new issue