commit
73eed452b9
@ -0,0 +1,107 @@ |
||||
/*
|
||||
* Copyright (C) 2016 by NXP Semiconductors Inc. |
||||
* Date & Time support for PCF2127 RTC |
||||
*/ |
||||
|
||||
/* #define DEBUG */ |
||||
|
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <dm.h> |
||||
#include <i2c.h> |
||||
#include <rtc.h> |
||||
|
||||
#define PCF2127_REG_CTRL1 (0x00) |
||||
#define PCF2127_REG_CTRL2 (0x01) |
||||
#define PCF2127_REG_CTRL3 (0x02) |
||||
#define PCF2127_REG_SC (0x03) /* datetime */ |
||||
#define PCF2127_REG_MN (0x04) |
||||
#define PCF2127_REG_HR (0x05) |
||||
#define PCF2127_REG_DM (0x06) |
||||
#define PCF2127_REG_DW (0x07) |
||||
#define PCF2127_REG_MO (0x08) |
||||
#define PCF2127_REG_YR (0x09) |
||||
|
||||
static int pcf2127_rtc_set(struct udevice *dev, const struct rtc_time *tm) |
||||
{ |
||||
uchar buf[8]; |
||||
int i = 0; |
||||
|
||||
/* start register address */ |
||||
buf[i++] = PCF2127_REG_SC; |
||||
|
||||
/* hours, minutes and seconds */ |
||||
buf[i++] = bin2bcd(tm->tm_sec); |
||||
buf[i++] = bin2bcd(tm->tm_min); |
||||
buf[i++] = bin2bcd(tm->tm_hour); |
||||
buf[i++] = bin2bcd(tm->tm_mday); |
||||
buf[i++] = tm->tm_wday & 0x07; |
||||
|
||||
/* month, 1 - 12 */ |
||||
buf[i++] = bin2bcd(tm->tm_mon + 1); |
||||
|
||||
/* year */ |
||||
buf[i++] = bin2bcd(tm->tm_year % 100); |
||||
|
||||
/* write register's data */ |
||||
if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0) |
||||
return -1; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int pcf2127_rtc_get(struct udevice *dev, struct rtc_time *tm) |
||||
{ |
||||
int rel = 0; |
||||
uchar buf[10] = { PCF2127_REG_CTRL1 }; |
||||
|
||||
if (dm_i2c_write(dev, PCF2127_REG_CTRL1, buf, 1) < 0) |
||||
return -1; |
||||
if (dm_i2c_read(dev, PCF2127_REG_CTRL1, buf, sizeof(buf)) < 0) |
||||
return -1; |
||||
|
||||
if (buf[PCF2127_REG_CTRL3] & 0x04) |
||||
puts("### Warning: RTC Low Voltage - date/time not reliable\n"); |
||||
|
||||
tm->tm_sec = bcd2bin(buf[PCF2127_REG_SC] & 0x7F); |
||||
tm->tm_min = bcd2bin(buf[PCF2127_REG_MN] & 0x7F); |
||||
tm->tm_hour = bcd2bin(buf[PCF2127_REG_HR] & 0x3F); |
||||
tm->tm_mday = bcd2bin(buf[PCF2127_REG_DM] & 0x3F); |
||||
tm->tm_mon = bcd2bin(buf[PCF2127_REG_MO] & 0x1F) - 1; |
||||
tm->tm_year = bcd2bin(buf[PCF2127_REG_YR]) + 1900; |
||||
if (tm->tm_year < 1970) |
||||
tm->tm_year += 100; /* assume we are in 1970...2069 */ |
||||
tm->tm_wday = buf[PCF2127_REG_DW] & 0x07; |
||||
tm->tm_yday = 0; |
||||
tm->tm_isdst = 0; |
||||
|
||||
debug("Get DATE: %4d-%02d-%02d (wday=%d) TIME: %2d:%02d:%02d\n", |
||||
tm->tm_year, tm->tm_mon, tm->tm_mday, tm->tm_wday, |
||||
tm->tm_hour, tm->tm_min, tm->tm_sec); |
||||
|
||||
return rel; |
||||
} |
||||
|
||||
static int pcf2127_rtc_reset(struct udevice *dev) |
||||
{ |
||||
/*Doing nothing here*/ |
||||
return 0; |
||||
} |
||||
|
||||
static const struct rtc_ops pcf2127_rtc_ops = { |
||||
.get = pcf2127_rtc_get, |
||||
.set = pcf2127_rtc_set, |
||||
.reset = pcf2127_rtc_reset, |
||||
}; |
||||
|
||||
static const struct udevice_id pcf2127_rtc_ids[] = { |
||||
{ .compatible = "pcf2127-rtc" }, |
||||
{ } |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(rtc_pcf2127) = { |
||||
.name = "rtc-pcf2127", |
||||
.id = UCLASS_RTC, |
||||
.of_match = pcf2127_rtc_ids, |
||||
.ops = &pcf2127_rtc_ops, |
||||
}; |
@ -0,0 +1,255 @@ |
||||
/*
|
||||
* MISC driver for TI MUSB Glue. |
||||
* |
||||
* (C) Copyright 2016 |
||||
* Texas Instruments Incorporated, <www.ti.com> |
||||
* |
||||
* SPDX-License-Identifier: GPL-2.0+ |
||||
*/ |
||||
#include <common.h> |
||||
#include <command.h> |
||||
#include <console.h> |
||||
#include <dm.h> |
||||
#include <linux/usb/otg.h> |
||||
#include <dm/device-internal.h> |
||||
#include <dm/lists.h> |
||||
|
||||
#include <asm/io.h> |
||||
#include <asm/omap_musb.h> |
||||
#include "musb_uboot.h" |
||||
|
||||
DECLARE_GLOBAL_DATA_PTR; |
||||
|
||||
#ifdef CONFIG_DM_USB |
||||
|
||||
/* USB 2.0 PHY Control */ |
||||
#define CM_PHY_PWRDN (1 << 0) |
||||
#define CM_PHY_OTG_PWRDN (1 << 1) |
||||
#define OTGVDET_EN (1 << 19) |
||||
#define OTGSESSENDEN (1 << 20) |
||||
|
||||
#define AM335X_USB1_CTRL 0x8 |
||||
|
||||
struct ti_musb_platdata { |
||||
void *base; |
||||
void *ctrl_mod_base; |
||||
struct musb_hdrc_platform_data plat; |
||||
struct musb_hdrc_config musb_config; |
||||
struct omap_musb_board_data otg_board_data; |
||||
}; |
||||
|
||||
static int ti_musb_get_usb_index(int node) |
||||
{ |
||||
const void *fdt = gd->fdt_blob; |
||||
int i = 0; |
||||
char path[64]; |
||||
const char *alias_path; |
||||
char alias[16]; |
||||
|
||||
fdt_get_path(fdt, node, path, sizeof(path)); |
||||
|
||||
do { |
||||
snprintf(alias, sizeof(alias), "usb%d", i); |
||||
alias_path = fdt_get_alias(fdt, alias); |
||||
if (alias_path == NULL) { |
||||
debug("USB index not found\n"); |
||||
return -ENOENT; |
||||
} |
||||
|
||||
if (!strcmp(path, alias_path)) |
||||
return i; |
||||
|
||||
i++; |
||||
} while (alias_path); |
||||
|
||||
return -ENOENT; |
||||
} |
||||
|
||||
static void ti_musb_set_phy_power(struct udevice *dev, u8 on) |
||||
{ |
||||
struct ti_musb_platdata *platdata = dev_get_platdata(dev); |
||||
|
||||
if (on) { |
||||
clrsetbits_le32(platdata->ctrl_mod_base, |
||||
CM_PHY_PWRDN | CM_PHY_OTG_PWRDN, |
||||
OTGVDET_EN | OTGSESSENDEN); |
||||
} else { |
||||
clrsetbits_le32(platdata->ctrl_mod_base, 0, |
||||
CM_PHY_PWRDN | CM_PHY_OTG_PWRDN); |
||||
} |
||||
} |
||||
|
||||
static int ti_musb_ofdata_to_platdata(struct udevice *dev) |
||||
{ |
||||
struct ti_musb_platdata *platdata = dev_get_platdata(dev); |
||||
const void *fdt = gd->fdt_blob; |
||||
int node = dev->of_offset; |
||||
int phys; |
||||
int ctrl_mod; |
||||
int usb_index; |
||||
|
||||
platdata->base = (void *)dev_get_addr_index(dev, 1); |
||||
|
||||
phys = fdtdec_lookup_phandle(fdt, node, "phys"); |
||||
ctrl_mod = fdtdec_lookup_phandle(fdt, phys, "ti,ctrl_mod"); |
||||
platdata->ctrl_mod_base = (void *)fdtdec_get_addr(fdt, ctrl_mod, "reg"); |
||||
usb_index = ti_musb_get_usb_index(node); |
||||
switch (usb_index) { |
||||
case 1: |
||||
platdata->ctrl_mod_base += AM335X_USB1_CTRL; |
||||
case 0: |
||||
default: |
||||
break; |
||||
} |
||||
|
||||
platdata->musb_config.multipoint = fdtdec_get_int(fdt, node, |
||||
"mentor,multipoint", |
||||
-1); |
||||
if (platdata->musb_config.multipoint < 0) { |
||||
error("MUSB multipoint DT entry missing\n"); |
||||
return -ENOENT; |
||||
} |
||||
|
||||
platdata->musb_config.dyn_fifo = 1; |
||||
|
||||
platdata->musb_config.num_eps = fdtdec_get_int(fdt, node, |
||||
"mentor,num-eps", -1); |
||||
if (platdata->musb_config.num_eps < 0) { |
||||
error("MUSB num-eps DT entry missing\n"); |
||||
return -ENOENT; |
||||
} |
||||
|
||||
platdata->musb_config.ram_bits = fdtdec_get_int(fdt, node, |
||||
"mentor,ram-bits", -1); |
||||
if (platdata->musb_config.ram_bits < 0) { |
||||
error("MUSB ram-bits DT entry missing\n"); |
||||
return -ENOENT; |
||||
} |
||||
|
||||
platdata->otg_board_data.set_phy_power = ti_musb_set_phy_power; |
||||
platdata->otg_board_data.dev = dev; |
||||
platdata->plat.config = &platdata->musb_config; |
||||
|
||||
platdata->plat.power = fdtdec_get_int(fdt, node, "mentor,power", -1); |
||||
if (platdata->plat.power < 0) { |
||||
error("MUSB mentor,power DT entry missing\n"); |
||||
return -ENOENT; |
||||
} |
||||
|
||||
platdata->plat.platform_ops = &musb_dsps_ops; |
||||
platdata->plat.board_data = &platdata->otg_board_data; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int ti_musb_host_probe(struct udevice *dev) |
||||
{ |
||||
struct musb_host_data *host = dev_get_priv(dev); |
||||
struct ti_musb_platdata *platdata = dev_get_platdata(dev); |
||||
struct usb_bus_priv *priv = dev_get_uclass_priv(dev); |
||||
struct omap_musb_board_data *otg_board_data; |
||||
int ret; |
||||
|
||||
priv->desc_before_addr = true; |
||||
|
||||
otg_board_data = &platdata->otg_board_data; |
||||
|
||||
host->host = musb_init_controller(&platdata->plat, |
||||
(struct device *)otg_board_data, |
||||
platdata->base); |
||||
if (!host->host) |
||||
return -EIO; |
||||
|
||||
ret = musb_lowlevel_init(host); |
||||
|
||||
return ret; |
||||
} |
||||
|
||||
static int ti_musb_host_remove(struct udevice *dev) |
||||
{ |
||||
struct musb_host_data *host = dev_get_priv(dev); |
||||
|
||||
musb_stop(host->host); |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
static int ti_musb_host_ofdata_to_platdata(struct udevice *dev) |
||||
{ |
||||
struct ti_musb_platdata *platdata = dev_get_platdata(dev); |
||||
const void *fdt = gd->fdt_blob; |
||||
int node = dev->of_offset; |
||||
int ret; |
||||
|
||||
ret = ti_musb_ofdata_to_platdata(dev); |
||||
if (ret) { |
||||
error("platdata dt parse error\n"); |
||||
return ret; |
||||
} |
||||
|
||||
platdata->plat.mode = MUSB_HOST; |
||||
|
||||
return 0; |
||||
} |
||||
|
||||
U_BOOT_DRIVER(ti_musb_host) = { |
||||
.name = "ti-musb-host", |
||||
.id = UCLASS_USB, |
||||
.ofdata_to_platdata = ti_musb_host_ofdata_to_platdata, |
||||
.probe = ti_musb_host_probe, |
||||
.remove = ti_musb_host_remove, |
||||
.ops = &musb_usb_ops, |
||||
.platdata_auto_alloc_size = sizeof(struct ti_musb_platdata), |
||||
.priv_auto_alloc_size = sizeof(struct musb_host_data), |
||||
}; |
||||
|
||||
static int ti_musb_wrapper_bind(struct udevice *parent) |
||||
{ |
||||
const void *fdt = gd->fdt_blob; |
||||
int node; |
||||
int ret; |
||||
|
||||
for (node = fdt_first_subnode(fdt, parent->of_offset); node > 0; |
||||
node = fdt_next_subnode(fdt, node)) { |
||||
struct udevice *dev; |
||||
const char *name = fdt_get_name(fdt, node, NULL); |
||||
enum usb_dr_mode dr_mode; |
||||
struct driver *drv; |
||||
|
||||
if (strncmp(name, "usb@", 4)) |
||||
continue; |
||||
|
||||
dr_mode = usb_get_dr_mode(node); |
||||
switch (dr_mode) { |
||||
case USB_DR_MODE_PERIPHERAL: |
||||
/* Bind MUSB device */ |
||||
break; |
||||
case USB_DR_MODE_HOST: |
||||
/* Bind MUSB host */ |
||||
ret = device_bind_driver_to_node(parent, "ti-musb-host", |
||||
name, node, &dev); |
||||
if (ret) { |
||||
error("musb - not able to bind usb host node\n"); |
||||
return ret; |
||||
} |
||||
break; |
||||
default: |
||||
break; |
||||
}; |
||||
} |
||||
return 0; |
||||
} |
||||
|
||||
static const struct udevice_id ti_musb_ids[] = { |
||||
{ .compatible = "ti,am33xx-usb" }, |
||||
{ } |
||||
}; |
||||
|
||||
U_BOOT_DRIVER(ti_musb_wrapper) = { |
||||
.name = "ti-musb-wrapper", |
||||
.id = UCLASS_MISC, |
||||
.of_match = ti_musb_ids, |
||||
.bind = ti_musb_wrapper_bind, |
||||
}; |
||||
|
||||
#endif /* CONFIG_DM_USB */ |
Loading…
Reference in new issue