diff options
Diffstat (limited to 'drivers')
37 files changed, 1690 insertions, 1558 deletions
diff --git a/drivers/Kconfig b/drivers/Kconfig index a5f24d7..a736386 100644 --- a/drivers/Kconfig +++ b/drivers/Kconfig @@ -30,8 +30,6 @@ source "drivers/fpga/Kconfig" source "drivers/gpio/Kconfig" -source "drivers/hwmon/Kconfig" - source "drivers/i2c/Kconfig" source "drivers/input/Kconfig" diff --git a/drivers/Makefile b/drivers/Makefile index 64c39d3..058bccb 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -74,7 +74,6 @@ obj-$(CONFIG_CPU) += cpu/ obj-y += crypto/ obj-y += firmware/ obj-$(CONFIG_FPGA) += fpga/ -obj-y += hwmon/ obj-y += misc/ obj-$(CONFIG_MMC) += mmc/ obj-y += pcmcia/ @@ -87,7 +86,6 @@ obj-y += spmi/ obj-y += sysreset/ obj-y += timer/ obj-y += tpm/ -obj-y += twserial/ obj-y += video/ obj-y += watchdog/ obj-$(CONFIG_QE) += qe/ diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig index 6cbe145..931defd 100644 --- a/drivers/block/Kconfig +++ b/drivers/block/Kconfig @@ -59,3 +59,11 @@ config DWC_AHCI Synopsys DWC AHCI module. endmenu + +config IDE + bool "Support IDE controllers" + help + Enables support for IDE (Integrated Drive Electronics) hard drives. + This allows access to raw blocks and filesystems on an IDE drive + from U-Boot. See also CMD_IDE which provides an 'ide' command for + performing various IDE operations. diff --git a/drivers/block/Makefile b/drivers/block/Makefile index d89c8b0..0645096 100644 --- a/drivers/block/Makefile +++ b/drivers/block/Makefile @@ -17,6 +17,7 @@ obj-$(CONFIG_DM_SCSI) += scsi-uclass.o obj-$(CONFIG_SCSI_AHCI) += ahci.o obj-$(CONFIG_DWC_AHSATA) += dwc_ahsata.o obj-$(CONFIG_FSL_SATA) += fsl_sata.o +obj-$(CONFIG_IDE) += ide.o obj-$(CONFIG_IDE_FTIDE020) += ftide020.o obj-$(CONFIG_LIBATA) += libata.o obj-$(CONFIG_MVSATA_IDE) += mvsata_ide.o diff --git a/drivers/block/ide.c b/drivers/block/ide.c new file mode 100644 index 0000000..ac5b91c --- /dev/null +++ b/drivers/block/ide.c @@ -0,0 +1,1231 @@ +/* + * (C) Copyright 2000-2011 + * Wolfgang Denk, DENX Software Engineering, wd@denx.de. + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <ata.h> +#include <dm.h> +#include <ide.h> +#include <watchdog.h> +#include <asm/io.h> + +#ifdef __PPC__ +# define EIEIO __asm__ volatile ("eieio") +# define SYNC __asm__ volatile ("sync") +#else +# define EIEIO /* nothing */ +# define SYNC /* nothing */ +#endif + +/* Current offset for IDE0 / IDE1 bus access */ +ulong ide_bus_offset[CONFIG_SYS_IDE_MAXBUS] = { +#if defined(CONFIG_SYS_ATA_IDE0_OFFSET) + CONFIG_SYS_ATA_IDE0_OFFSET, +#endif +#if defined(CONFIG_SYS_ATA_IDE1_OFFSET) && (CONFIG_SYS_IDE_MAXBUS > 1) + CONFIG_SYS_ATA_IDE1_OFFSET, +#endif +}; + +static int ide_bus_ok[CONFIG_SYS_IDE_MAXBUS]; + +struct blk_desc ide_dev_desc[CONFIG_SYS_IDE_MAXDEVICE]; + +#define IDE_TIME_OUT 2000 /* 2 sec timeout */ + +#define ATAPI_TIME_OUT 7000 /* 7 sec timeout (5 sec seems to work...) */ + +#define IDE_SPIN_UP_TIME_OUT 5000 /* 5 sec spin-up timeout */ + +#ifndef CONFIG_SYS_ATA_PORT_ADDR +#define CONFIG_SYS_ATA_PORT_ADDR(port) (port) +#endif + +#ifndef CONFIG_IDE_LED /* define LED macros, they are not used anyways */ +# define DEVICE_LED(x) 0 +# define LED_IDE1 1 +# define LED_IDE2 2 +#endif + +#ifdef CONFIG_IDE_RESET +extern void ide_set_reset(int idereset); + +static void ide_reset(void) +{ + int i; + + for (i = 0; i < CONFIG_SYS_IDE_MAXBUS; ++i) + ide_bus_ok[i] = 0; + for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) + ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; + + ide_set_reset(1); /* assert reset */ + + /* the reset signal shall be asserted for et least 25 us */ + udelay(25); + + WATCHDOG_RESET(); + + /* de-assert RESET signal */ + ide_set_reset(0); + + /* wait 250 ms */ + for (i = 0; i < 250; ++i) + udelay(1000); +} +#else +#define ide_reset() /* dummy */ +#endif /* CONFIG_IDE_RESET */ + +/* + * Wait until Busy bit is off, or timeout (in ms) + * Return last status + */ +static uchar ide_wait(int dev, ulong t) +{ + ulong delay = 10 * t; /* poll every 100 us */ + uchar c; + + while ((c = ide_inb(dev, ATA_STATUS)) & ATA_STAT_BUSY) { + udelay(100); + if (delay-- == 0) + break; + } + return c; +} + +/* + * copy src to dest, skipping leading and trailing blanks and null + * terminate the string + * "len" is the size of available memory including the terminating '\0' + */ +static void ident_cpy(unsigned char *dst, unsigned char *src, + unsigned int len) +{ + unsigned char *end, *last; + + last = dst; + end = src + len - 1; + + /* reserve space for '\0' */ + if (len < 2) + goto OUT; + + /* skip leading white space */ + while ((*src) && (src < end) && (*src == ' ')) + ++src; + + /* copy string, omitting trailing white space */ + while ((*src) && (src < end)) { + *dst++ = *src; + if (*src++ != ' ') + last = dst; + } +OUT: + *last = '\0'; +} + +#ifdef CONFIG_ATAPI +/**************************************************************************** + * ATAPI Support + */ + +#if defined(CONFIG_IDE_SWAP_IO) +/* since ATAPI may use commands with not 4 bytes alligned length + * we have our own transfer functions, 2 bytes alligned */ +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) +{ + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + + debug("in output data shorts base for read is %lx\n", + (unsigned long) pbuf); + + while (shorts--) { + EIEIO; + *pbuf = *dbuf++; + } +} + +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) +{ + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + + debug("in input data shorts base for read is %lx\n", + (unsigned long) pbuf); + + while (shorts--) { + EIEIO; + *dbuf++ = *pbuf; + } +} + +#else /* ! CONFIG_IDE_SWAP_IO */ +__weak void ide_output_data_shorts(int dev, ushort *sect_buf, int shorts) +{ + outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); +} + +__weak void ide_input_data_shorts(int dev, ushort *sect_buf, int shorts) +{ + insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, shorts); +} + +#endif /* CONFIG_IDE_SWAP_IO */ + +/* + * Wait until (Status & mask) == res, or timeout (in ms) + * Return last status + * This is used since some ATAPI CD ROMs clears their Busy Bit first + * and then they set their DRQ Bit + */ +static uchar atapi_wait_mask(int dev, ulong t, uchar mask, uchar res) +{ + ulong delay = 10 * t; /* poll every 100 us */ + uchar c; + + /* prevents to read the status before valid */ + c = ide_inb(dev, ATA_DEV_CTL); + + while (((c = ide_inb(dev, ATA_STATUS)) & mask) != res) { + /* break if error occurs (doesn't make sense to wait more) */ + if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) + break; + udelay(100); + if (delay-- == 0) + break; + } + return c; +} + +/* + * issue an atapi command + */ +unsigned char atapi_issue(int device, unsigned char *ccb, int ccblen, + unsigned char *buffer, int buflen) +{ + unsigned char c, err, mask, res; + int n; + + ide_led(DEVICE_LED(device), 1); /* LED on */ + + /* Select device + */ + mask = ATA_STAT_BUSY | ATA_STAT_DRQ; + res = 0; + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); + if ((c & mask) != res) { + printf("ATAPI_ISSUE: device %d not ready status %X\n", device, + c); + err = 0xFF; + goto AI_OUT; + } + /* write taskfile */ + ide_outb(device, ATA_ERROR_REG, 0); /* no DMA, no overlaped */ + ide_outb(device, ATA_SECT_CNT, 0); + ide_outb(device, ATA_SECT_NUM, 0); + ide_outb(device, ATA_CYL_LOW, (unsigned char) (buflen & 0xFF)); + ide_outb(device, ATA_CYL_HIGH, + (unsigned char) ((buflen >> 8) & 0xFF)); + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + + ide_outb(device, ATA_COMMAND, ATAPI_CMD_PACKET); + udelay(50); + + mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR; + res = ATA_STAT_DRQ; + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); + + if ((c & mask) != res) { /* DRQ must be 1, BSY 0 */ + printf("ATAPI_ISSUE: Error (no IRQ) before sending ccb dev %d status 0x%02x\n", + device, c); + err = 0xFF; + goto AI_OUT; + } + + /* write command block */ + ide_output_data_shorts(device, (unsigned short *)ccb, ccblen / 2); + + /* ATAPI Command written wait for completition */ + udelay(5000); /* device must set bsy */ + + mask = ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR; + /* + * if no data wait for DRQ = 0 BSY = 0 + * if data wait for DRQ = 1 BSY = 0 + */ + res = 0; + if (buflen) + res = ATA_STAT_DRQ; + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); + if ((c & mask) != res) { + if (c & ATA_STAT_ERR) { + err = (ide_inb(device, ATA_ERROR_REG)) >> 4; + debug("atapi_issue 1 returned sense key %X status %02X\n", + err, c); + } else { + printf("ATAPI_ISSUE: (no DRQ) after sending ccb (%x) status 0x%02x\n", + ccb[0], c); + err = 0xFF; + } + goto AI_OUT; + } + n = ide_inb(device, ATA_CYL_HIGH); + n <<= 8; + n += ide_inb(device, ATA_CYL_LOW); + if (n > buflen) { + printf("ERROR, transfer bytes %d requested only %d\n", n, + buflen); + err = 0xff; + goto AI_OUT; + } + if ((n == 0) && (buflen < 0)) { + printf("ERROR, transfer bytes %d requested %d\n", n, buflen); + err = 0xff; + goto AI_OUT; + } + if (n != buflen) { + debug("WARNING, transfer bytes %d not equal with requested %d\n", + n, buflen); + } + if (n != 0) { /* data transfer */ + debug("ATAPI_ISSUE: %d Bytes to transfer\n", n); + /* we transfer shorts */ + n >>= 1; + /* ok now decide if it is an in or output */ + if ((ide_inb(device, ATA_SECT_CNT) & 0x02) == 0) { + debug("Write to device\n"); + ide_output_data_shorts(device, (unsigned short *)buffer, + n); + } else { + debug("Read from device @ %p shorts %d\n", buffer, n); + ide_input_data_shorts(device, (unsigned short *)buffer, + n); + } + } + udelay(5000); /* seems that some CD ROMs need this... */ + mask = ATA_STAT_BUSY | ATA_STAT_ERR; + res = 0; + c = atapi_wait_mask(device, ATAPI_TIME_OUT, mask, res); + if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { + err = (ide_inb(device, ATA_ERROR_REG) >> 4); + debug("atapi_issue 2 returned sense key %X status %X\n", err, + c); + } else { + err = 0; + } +AI_OUT: + ide_led(DEVICE_LED(device), 0); /* LED off */ + return err; +} + +/* + * sending the command to atapi_issue. If an status other than good + * returns, an request_sense will be issued + */ + +#define ATAPI_DRIVE_NOT_READY 100 +#define ATAPI_UNIT_ATTN 10 + +unsigned char atapi_issue_autoreq(int device, + unsigned char *ccb, + int ccblen, + unsigned char *buffer, int buflen) +{ + unsigned char sense_data[18], sense_ccb[12]; + unsigned char res, key, asc, ascq; + int notready, unitattn; + + unitattn = ATAPI_UNIT_ATTN; + notready = ATAPI_DRIVE_NOT_READY; + +retry: + res = atapi_issue(device, ccb, ccblen, buffer, buflen); + if (res == 0) + return 0; /* Ok */ + + if (res == 0xFF) + return 0xFF; /* error */ + + debug("(auto_req)atapi_issue returned sense key %X\n", res); + + memset(sense_ccb, 0, sizeof(sense_ccb)); + memset(sense_data, 0, sizeof(sense_data)); + sense_ccb[0] = ATAPI_CMD_REQ_SENSE; + sense_ccb[4] = 18; /* allocation Length */ + + res = atapi_issue(device, sense_ccb, 12, sense_data, 18); + key = (sense_data[2] & 0xF); + asc = (sense_data[12]); + ascq = (sense_data[13]); + + debug("ATAPI_CMD_REQ_SENSE returned %x\n", res); + debug(" Sense page: %02X key %02X ASC %02X ASCQ %02X\n", + sense_data[0], key, asc, ascq); + + if ((key == 0)) + return 0; /* ok device ready */ + + if ((key == 6) || (asc == 0x29) || (asc == 0x28)) { /* Unit Attention */ + if (unitattn-- > 0) { + udelay(200 * 1000); + goto retry; + } + printf("Unit Attention, tried %d\n", ATAPI_UNIT_ATTN); + goto error; + } + if ((asc == 0x4) && (ascq == 0x1)) { + /* not ready, but will be ready soon */ + if (notready-- > 0) { + udelay(200 * 1000); + goto retry; + } + printf("Drive not ready, tried %d times\n", + ATAPI_DRIVE_NOT_READY); + goto error; + } + if (asc == 0x3a) { + debug("Media not present\n"); + goto error; + } + + printf("ERROR: Unknown Sense key %02X ASC %02X ASCQ %02X\n", key, asc, + ascq); +error: + debug("ERROR Sense key %02X ASC %02X ASCQ %02X\n", key, asc, ascq); + return 0xFF; +} + +/* + * atapi_read: + * we transfer only one block per command, since the multiple DRQ per + * command is not yet implemented + */ +#define ATAPI_READ_MAX_BYTES 2048 /* we read max 2kbytes */ +#define ATAPI_READ_BLOCK_SIZE 2048 /* assuming CD part */ +#define ATAPI_READ_MAX_BLOCK (ATAPI_READ_MAX_BYTES/ATAPI_READ_BLOCK_SIZE) + +ulong atapi_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) +{ + int device = block_dev->devnum; + ulong n = 0; + unsigned char ccb[12]; /* Command descriptor block */ + ulong cnt; + + debug("atapi_read dev %d start " LBAF " blocks " LBAF + " buffer at %lX\n", device, blknr, blkcnt, (ulong) buffer); + + do { + if (blkcnt > ATAPI_READ_MAX_BLOCK) + cnt = ATAPI_READ_MAX_BLOCK; + else + cnt = blkcnt; + + ccb[0] = ATAPI_CMD_READ_12; + ccb[1] = 0; /* reserved */ + ccb[2] = (unsigned char) (blknr >> 24) & 0xFF; /* MSB Block */ + ccb[3] = (unsigned char) (blknr >> 16) & 0xFF; /* */ + ccb[4] = (unsigned char) (blknr >> 8) & 0xFF; + ccb[5] = (unsigned char) blknr & 0xFF; /* LSB Block */ + ccb[6] = (unsigned char) (cnt >> 24) & 0xFF; /* MSB Block cnt */ + ccb[7] = (unsigned char) (cnt >> 16) & 0xFF; + ccb[8] = (unsigned char) (cnt >> 8) & 0xFF; + ccb[9] = (unsigned char) cnt & 0xFF; /* LSB Block */ + ccb[10] = 0; /* reserved */ + ccb[11] = 0; /* reserved */ + + if (atapi_issue_autoreq(device, ccb, 12, + (unsigned char *)buffer, + cnt * ATAPI_READ_BLOCK_SIZE) + == 0xFF) { + return n; + } + n += cnt; + blkcnt -= cnt; + blknr += cnt; + buffer += (cnt * ATAPI_READ_BLOCK_SIZE); + } while (blkcnt > 0); + return n; +} + +static void atapi_inquiry(struct blk_desc *dev_desc) +{ + unsigned char ccb[12]; /* Command descriptor block */ + unsigned char iobuf[64]; /* temp buf */ + unsigned char c; + int device; + + device = dev_desc->devnum; + dev_desc->type = DEV_TYPE_UNKNOWN; /* not yet valid */ + dev_desc->block_read = atapi_read; + + memset(ccb, 0, sizeof(ccb)); + memset(iobuf, 0, sizeof(iobuf)); + + ccb[0] = ATAPI_CMD_INQUIRY; + ccb[4] = 40; /* allocation Legnth */ + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 40); + + debug("ATAPI_CMD_INQUIRY returned %x\n", c); + if (c != 0) + return; + + /* copy device ident strings */ + ident_cpy((unsigned char *)dev_desc->vendor, &iobuf[8], 8); + ident_cpy((unsigned char *)dev_desc->product, &iobuf[16], 16); + ident_cpy((unsigned char *)dev_desc->revision, &iobuf[32], 5); + + dev_desc->lun = 0; + dev_desc->lba = 0; + dev_desc->blksz = 0; + dev_desc->log2blksz = LOG2_INVALID(typeof(dev_desc->log2blksz)); + dev_desc->type = iobuf[0] & 0x1f; + + if ((iobuf[1] & 0x80) == 0x80) + dev_desc->removable = 1; + else + dev_desc->removable = 0; + + memset(ccb, 0, sizeof(ccb)); + memset(iobuf, 0, sizeof(iobuf)); + ccb[0] = ATAPI_CMD_START_STOP; + ccb[4] = 0x03; /* start */ + + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0); + + debug("ATAPI_CMD_START_STOP returned %x\n", c); + if (c != 0) + return; + + memset(ccb, 0, sizeof(ccb)); + memset(iobuf, 0, sizeof(iobuf)); + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 0); + + debug("ATAPI_CMD_UNIT_TEST_READY returned %x\n", c); + if (c != 0) + return; + + memset(ccb, 0, sizeof(ccb)); + memset(iobuf, 0, sizeof(iobuf)); + ccb[0] = ATAPI_CMD_READ_CAP; + c = atapi_issue_autoreq(device, ccb, 12, (unsigned char *)iobuf, 8); + debug("ATAPI_CMD_READ_CAP returned %x\n", c); + if (c != 0) + return; + + debug("Read Cap: LBA %02X%02X%02X%02X blksize %02X%02X%02X%02X\n", + iobuf[0], iobuf[1], iobuf[2], iobuf[3], + iobuf[4], iobuf[5], iobuf[6], iobuf[7]); + + dev_desc->lba = ((unsigned long) iobuf[0] << 24) + + ((unsigned long) iobuf[1] << 16) + + ((unsigned long) iobuf[2] << 8) + ((unsigned long) iobuf[3]); + dev_desc->blksz = ((unsigned long) iobuf[4] << 24) + + ((unsigned long) iobuf[5] << 16) + + ((unsigned long) iobuf[6] << 8) + ((unsigned long) iobuf[7]); + dev_desc->log2blksz = LOG2(dev_desc->blksz); +#ifdef CONFIG_LBA48 + /* ATAPI devices cannot use 48bit addressing (ATA/ATAPI v7) */ + dev_desc->lba48 = 0; +#endif + return; +} + +#endif /* CONFIG_ATAPI */ + +static void ide_ident(struct blk_desc *dev_desc) +{ + unsigned char c; + hd_driveid_t iop; + +#ifdef CONFIG_ATAPI + int retries = 0; +#endif + int device; + + device = dev_desc->devnum; + printf(" Device %d: ", device); + + ide_led(DEVICE_LED(device), 1); /* LED on */ + /* Select device + */ + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + dev_desc->if_type = IF_TYPE_IDE; +#ifdef CONFIG_ATAPI + + retries = 0; + + /* Warning: This will be tricky to read */ + while (retries <= 1) { + /* check signature */ + if ((ide_inb(device, ATA_SECT_CNT) == 0x01) && + (ide_inb(device, ATA_SECT_NUM) == 0x01) && + (ide_inb(device, ATA_CYL_LOW) == 0x14) && + (ide_inb(device, ATA_CYL_HIGH) == 0xEB)) { + /* ATAPI Signature found */ + dev_desc->if_type = IF_TYPE_ATAPI; + /* + * Start Ident Command + */ + ide_outb(device, ATA_COMMAND, ATAPI_CMD_IDENT); + /* + * Wait for completion - ATAPI devices need more time + * to become ready + */ + c = ide_wait(device, ATAPI_TIME_OUT); + } else +#endif + { + /* + * Start Ident Command + */ + ide_outb(device, ATA_COMMAND, ATA_CMD_IDENT); + + /* + * Wait for completion + */ + c = ide_wait(device, IDE_TIME_OUT); + } + ide_led(DEVICE_LED(device), 0); /* LED off */ + + if (((c & ATA_STAT_DRQ) == 0) || + ((c & (ATA_STAT_FAULT | ATA_STAT_ERR)) != 0)) { +#ifdef CONFIG_ATAPI + { + /* + * Need to soft reset the device + * in case it's an ATAPI... + */ + debug("Retrying...\n"); + ide_outb(device, ATA_DEV_HD, + ATA_LBA | ATA_DEVICE(device)); + udelay(100000); + ide_outb(device, ATA_COMMAND, 0x08); + udelay(500000); /* 500 ms */ + } + /* + * Select device + */ + ide_outb(device, ATA_DEV_HD, + ATA_LBA | ATA_DEVICE(device)); + retries++; +#else + return; +#endif + } +#ifdef CONFIG_ATAPI + else + break; + } /* see above - ugly to read */ + + if (retries == 2) /* Not found */ + return; +#endif + + ide_input_swap_data(device, (ulong *)&iop, ATA_SECTORWORDS); + + ident_cpy((unsigned char *)dev_desc->revision, iop.fw_rev, + sizeof(dev_desc->revision)); + ident_cpy((unsigned char *)dev_desc->vendor, iop.model, + sizeof(dev_desc->vendor)); + ident_cpy((unsigned char *)dev_desc->product, iop.serial_no, + sizeof(dev_desc->product)); +#ifdef __LITTLE_ENDIAN + /* + * firmware revision, model, and serial number have Big Endian Byte + * order in Word. Convert all three to little endian. + * + * See CF+ and CompactFlash Specification Revision 2.0: + * 6.2.1.6: Identify Drive, Table 39 for more details + */ + + strswab(dev_desc->revision); + strswab(dev_desc->vendor); + strswab(dev_desc->product); +#endif /* __LITTLE_ENDIAN */ + + if ((iop.config & 0x0080) == 0x0080) + dev_desc->removable = 1; + else + dev_desc->removable = 0; + +#ifdef CONFIG_ATAPI + if (dev_desc->if_type == IF_TYPE_ATAPI) { + atapi_inquiry(dev_desc); + return; + } +#endif /* CONFIG_ATAPI */ + +#ifdef __BIG_ENDIAN + /* swap shorts */ + dev_desc->lba = (iop.lba_capacity << 16) | (iop.lba_capacity >> 16); +#else /* ! __BIG_ENDIAN */ + /* + * do not swap shorts on little endian + * + * See CF+ and CompactFlash Specification Revision 2.0: + * 6.2.1.6: Identfy Drive, Table 39, Word Address 57-58 for details. + */ + dev_desc->lba = iop.lba_capacity; +#endif /* __BIG_ENDIAN */ + +#ifdef CONFIG_LBA48 + if (iop.command_set_2 & 0x0400) { /* LBA 48 support */ + dev_desc->lba48 = 1; + dev_desc->lba = (unsigned long long) iop.lba48_capacity[0] | + ((unsigned long long) iop.lba48_capacity[1] << 16) | + ((unsigned long long) iop.lba48_capacity[2] << 32) | + ((unsigned long long) iop.lba48_capacity[3] << 48); + } else { + dev_desc->lba48 = 0; + } +#endif /* CONFIG_LBA48 */ + /* assuming HD */ + dev_desc->type = DEV_TYPE_HARDDISK; + dev_desc->blksz = ATA_BLOCKSIZE; + dev_desc->log2blksz = LOG2(dev_desc->blksz); + dev_desc->lun = 0; /* just to fill something in... */ + +#if 0 /* only used to test the powersaving mode, + * if enabled, the drive goes after 5 sec + * in standby mode */ + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + c = ide_wait(device, IDE_TIME_OUT); + ide_outb(device, ATA_SECT_CNT, 1); + ide_outb(device, ATA_LBA_LOW, 0); + ide_outb(device, ATA_LBA_MID, 0); + ide_outb(device, ATA_LBA_HIGH, 0); + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + ide_outb(device, ATA_COMMAND, 0xe3); + udelay(50); + c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */ +#endif +} + +__weak void ide_led(uchar led, uchar status) +{ +#if defined(CONFIG_IDE_LED) && defined(PER8_BASE) /* required by LED_PORT */ + static uchar led_buffer; /* Buffer for current LED status */ + + uchar *led_port = LED_PORT; + + if (status) /* switch LED on */ + led_buffer |= led; + else /* switch LED off */ + led_buffer &= ~led; + + *led_port = led_buffer; +#endif +} + +__weak void ide_outb(int dev, int port, unsigned char val) +{ + debug("ide_outb (dev= %d, port= 0x%x, val= 0x%02x) : @ 0x%08lx\n", + dev, port, val, + (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); + +#if defined(CONFIG_IDE_AHB) + if (port) { + /* write command */ + ide_write_register(dev, port, val); + } else { + /* write data */ + outb(val, (ATA_CURR_BASE(dev))); + } +#else + outb(val, (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); +#endif +} + +__weak unsigned char ide_inb(int dev, int port) +{ + uchar val; + +#if defined(CONFIG_IDE_AHB) + val = ide_read_register(dev, port); +#else + val = inb((ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port))); +#endif + + debug("ide_inb (dev= %d, port= 0x%x) : @ 0x%08lx -> 0x%02x\n", + dev, port, + (ATA_CURR_BASE(dev) + CONFIG_SYS_ATA_PORT_ADDR(port)), val); + return val; +} + +void ide_init(void) +{ + unsigned char c; + int i, bus; + +#ifdef CONFIG_IDE_8xx_PCCARD + extern int ide_devices_found; /* Initialized in check_ide_device() */ +#endif /* CONFIG_IDE_8xx_PCCARD */ + +#ifdef CONFIG_IDE_PREINIT + WATCHDOG_RESET(); + + if (ide_preinit()) { + puts("ide_preinit failed\n"); + return; + } +#endif /* CONFIG_IDE_PREINIT */ + + WATCHDOG_RESET(); + + /* + * Reset the IDE just to be sure. + * Light LED's to show + */ + ide_led((LED_IDE1 | LED_IDE2), 1); /* LED's on */ + + /* ATAPI Drives seems to need a proper IDE Reset */ + ide_reset(); + +#ifdef CONFIG_IDE_INIT_POSTRESET + WATCHDOG_RESET(); + + if (ide_init_postreset()) { + puts("ide_preinit_postreset failed\n"); + return; + } +#endif /* CONFIG_IDE_INIT_POSTRESET */ + + /* + * Wait for IDE to get ready. + * According to spec, this can take up to 31 seconds! + */ + for (bus = 0; bus < CONFIG_SYS_IDE_MAXBUS; ++bus) { + int dev = + bus * (CONFIG_SYS_IDE_MAXDEVICE / + CONFIG_SYS_IDE_MAXBUS); + +#ifdef CONFIG_IDE_8xx_PCCARD + /* Skip non-ide devices from probing */ + if ((ide_devices_found & (1 << bus)) == 0) { + ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */ + continue; + } +#endif + printf("Bus %d: ", bus); + + ide_bus_ok[bus] = 0; + + /* Select device + */ + udelay(100000); /* 100 ms */ + ide_outb(dev, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(dev)); + udelay(100000); /* 100 ms */ + i = 0; + do { + udelay(10000); /* 10 ms */ + + c = ide_inb(dev, ATA_STATUS); + i++; + if (i > (ATA_RESET_TIME * 100)) { + puts("** Timeout **\n"); + /* LED's off */ + ide_led((LED_IDE1 | LED_IDE2), 0); + return; + } + if ((i >= 100) && ((i % 100) == 0)) + putc('.'); + + } while (c & ATA_STAT_BUSY); + + if (c & (ATA_STAT_BUSY | ATA_STAT_FAULT)) { + puts("not available "); + debug("Status = 0x%02X ", c); +#ifndef CONFIG_ATAPI /* ATAPI Devices do not set DRDY */ + } else if ((c & ATA_STAT_READY) == 0) { + puts("not available "); + debug("Status = 0x%02X ", c); +#endif + } else { + puts("OK "); + ide_bus_ok[bus] = 1; + } + WATCHDOG_RESET(); + } + + putc('\n'); + + ide_led((LED_IDE1 | LED_IDE2), 0); /* LED's off */ + + for (i = 0; i < CONFIG_SYS_IDE_MAXDEVICE; ++i) { + int led = (IDE_BUS(i) == 0) ? LED_IDE1 : LED_IDE2; + ide_dev_desc[i].type = DEV_TYPE_UNKNOWN; + ide_dev_desc[i].if_type = IF_TYPE_IDE; + ide_dev_desc[i].devnum = i; + ide_dev_desc[i].part_type = PART_TYPE_UNKNOWN; + ide_dev_desc[i].blksz = 0; + ide_dev_desc[i].log2blksz = + LOG2_INVALID(typeof(ide_dev_desc[i].log2blksz)); + ide_dev_desc[i].lba = 0; +#ifndef CONFIG_BLK + ide_dev_desc[i].block_read = ide_read; + ide_dev_desc[i].block_write = ide_write; +#endif + if (!ide_bus_ok[IDE_BUS(i)]) + continue; + ide_led(led, 1); /* LED on */ + ide_ident(&ide_dev_desc[i]); + ide_led(led, 0); /* LED off */ + dev_print(&ide_dev_desc[i]); + + if ((ide_dev_desc[i].lba > 0) && (ide_dev_desc[i].blksz > 0)) { + /* initialize partition type */ + part_init(&ide_dev_desc[i]); + } + } + WATCHDOG_RESET(); +} + +/* We only need to swap data if we are running on a big endian cpu. */ +#if defined(__LITTLE_ENDIAN) +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) +{ + ide_input_data(dev, sect_buf, words); +} +#else +__weak void ide_input_swap_data(int dev, ulong *sect_buf, int words) +{ + volatile ushort *pbuf = + (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); + ushort *dbuf = (ushort *)sect_buf; + + debug("in input swap data base for read is %lx\n", + (unsigned long) pbuf); + + while (words--) { +#ifdef __MIPS__ + *dbuf++ = swab16p((u16 *)pbuf); + *dbuf++ = swab16p((u16 *)pbuf); +#else + *dbuf++ = ld_le16(pbuf); + *dbuf++ = ld_le16(pbuf); +#endif /* !MIPS */ + } +} +#endif /* __LITTLE_ENDIAN */ + + +#if defined(CONFIG_IDE_SWAP_IO) +__weak void ide_output_data(int dev, const ulong *sect_buf, int words) +{ + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + while (words--) { + EIEIO; + *pbuf = *dbuf++; + EIEIO; + *pbuf = *dbuf++; + } +} +#else /* ! CONFIG_IDE_SWAP_IO */ +__weak void ide_output_data(int dev, const ulong *sect_buf, int words) +{ +#if defined(CONFIG_IDE_AHB) + ide_write_data(dev, sect_buf, words); +#else + outsw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); +#endif +} +#endif /* CONFIG_IDE_SWAP_IO */ + +#if defined(CONFIG_IDE_SWAP_IO) +__weak void ide_input_data(int dev, ulong *sect_buf, int words) +{ + ushort *dbuf; + volatile ushort *pbuf; + + pbuf = (ushort *)(ATA_CURR_BASE(dev) + ATA_DATA_REG); + dbuf = (ushort *)sect_buf; + + debug("in input data base for read is %lx\n", (unsigned long) pbuf); + + while (words--) { + EIEIO; + *dbuf++ = *pbuf; + EIEIO; + *dbuf++ = *pbuf; + } +} +#else /* ! CONFIG_IDE_SWAP_IO */ +__weak void ide_input_data(int dev, ulong *sect_buf, int words) +{ +#if defined(CONFIG_IDE_AHB) + ide_read_data(dev, sect_buf, words); +#else + insw(ATA_CURR_BASE(dev) + ATA_DATA_REG, sect_buf, words << 1); +#endif +} + +#endif /* CONFIG_IDE_SWAP_IO */ + +#ifdef CONFIG_BLK +ulong ide_read(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) +#else +ulong ide_read(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, + void *buffer) +#endif +{ +#ifdef CONFIG_BLK + struct blk_desc *block_dev = dev_get_uclass_platdata(dev); +#endif + int device = block_dev->devnum; + ulong n = 0; + unsigned char c; + unsigned char pwrsave = 0; /* power save */ + +#ifdef CONFIG_LBA48 + unsigned char lba48 = 0; + + if (blknr & 0x0000fffff0000000ULL) { + /* more than 28 bits used, use 48bit mode */ + lba48 = 1; + } +#endif + debug("ide_read dev %d start " LBAF ", blocks " LBAF " buffer at %lX\n", + device, blknr, blkcnt, (ulong) buffer); + + ide_led(DEVICE_LED(device), 1); /* LED on */ + + /* Select device + */ + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + c = ide_wait(device, IDE_TIME_OUT); + + if (c & ATA_STAT_BUSY) { + printf("IDE read: device %d not ready\n", device); + goto IDE_READ_E; + } + + /* first check if the drive is in Powersaving mode, if yes, + * increase the timeout value */ + ide_outb(device, ATA_COMMAND, ATA_CMD_CHK_PWR); + udelay(50); + + c = ide_wait(device, IDE_TIME_OUT); /* can't take over 500 ms */ + + if (c & ATA_STAT_BUSY) { + printf("IDE read: device %d not ready\n", device); + goto IDE_READ_E; + } + if ((c & ATA_STAT_ERR) == ATA_STAT_ERR) { + printf("No Powersaving mode %X\n", c); + } else { + c = ide_inb(device, ATA_SECT_CNT); + debug("Powersaving %02X\n", c); + if (c == 0) + pwrsave = 1; + } + + + while (blkcnt-- > 0) { + c = ide_wait(device, IDE_TIME_OUT); + + if (c & ATA_STAT_BUSY) { + printf("IDE read: device %d not ready\n", device); + break; + } +#ifdef CONFIG_LBA48 + if (lba48) { + /* write high bits */ + ide_outb(device, ATA_SECT_CNT, 0); + ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); +#ifdef CONFIG_SYS_64BIT_LBA + ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF); + ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); +#else + ide_outb(device, ATA_LBA_MID, 0); + ide_outb(device, ATA_LBA_HIGH, 0); +#endif + } +#endif + ide_outb(device, ATA_SECT_CNT, 1); + ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); + ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF); + ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); + +#ifdef CONFIG_LBA48 + if (lba48) { + ide_outb(device, ATA_DEV_HD, + ATA_LBA | ATA_DEVICE(device)); + ide_outb(device, ATA_COMMAND, ATA_CMD_READ_EXT); + + } else +#endif + { + ide_outb(device, ATA_DEV_HD, ATA_LBA | + ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); + ide_outb(device, ATA_COMMAND, ATA_CMD_READ); + } + + udelay(50); + + if (pwrsave) { + /* may take up to 4 sec */ + c = ide_wait(device, IDE_SPIN_UP_TIME_OUT); + pwrsave = 0; + } else { + /* can't take over 500 ms */ + c = ide_wait(device, IDE_TIME_OUT); + } + + if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != + ATA_STAT_DRQ) { + printf("Error (no IRQ) dev %d blk " LBAF + ": status %#02x\n", device, blknr, c); + break; + } + + ide_input_data(device, buffer, ATA_SECTORWORDS); + (void) ide_inb(device, ATA_STATUS); /* clear IRQ */ + + ++n; + ++blknr; + buffer += ATA_BLOCKSIZE; + } +IDE_READ_E: + ide_led(DEVICE_LED(device), 0); /* LED off */ + return n; +} + +#ifdef CONFIG_BLK +ulong ide_write(struct udevice *dev, lbaint_t blknr, lbaint_t blkcnt, + const void *buffer) +#else +ulong ide_write(struct blk_desc *block_dev, lbaint_t blknr, lbaint_t blkcnt, + const void *buffer) +#endif +{ +#ifdef CONFIG_BLK + struct blk_desc *block_dev = dev_get_uclass_platdata(dev); +#endif + int device = block_dev->devnum; + ulong n = 0; + unsigned char c; + +#ifdef CONFIG_LBA48 + unsigned char lba48 = 0; + + if (blknr & 0x0000fffff0000000ULL) { + /* more than 28 bits used, use 48bit mode */ + lba48 = 1; + } +#endif + + ide_led(DEVICE_LED(device), 1); /* LED on */ + + /* Select device + */ + ide_outb(device, ATA_DEV_HD, ATA_LBA | ATA_DEVICE(device)); + + while (blkcnt-- > 0) { + c = ide_wait(device, IDE_TIME_OUT); + + if (c & ATA_STAT_BUSY) { + printf("IDE read: device %d not ready\n", device); + goto WR_OUT; + } +#ifdef CONFIG_LBA48 + if (lba48) { + /* write high bits */ + ide_outb(device, ATA_SECT_CNT, 0); + ide_outb(device, ATA_LBA_LOW, (blknr >> 24) & 0xFF); +#ifdef CONFIG_SYS_64BIT_LBA + ide_outb(device, ATA_LBA_MID, (blknr >> 32) & 0xFF); + ide_outb(device, ATA_LBA_HIGH, (blknr >> 40) & 0xFF); +#else + ide_outb(device, ATA_LBA_MID, 0); + ide_outb(device, ATA_LBA_HIGH, 0); +#endif + } +#endif + ide_outb(device, ATA_SECT_CNT, 1); + ide_outb(device, ATA_LBA_LOW, (blknr >> 0) & 0xFF); + ide_outb(device, ATA_LBA_MID, (blknr >> 8) & 0xFF); + ide_outb(device, ATA_LBA_HIGH, (blknr >> 16) & 0xFF); + +#ifdef CONFIG_LBA48 + if (lba48) { + ide_outb(device, ATA_DEV_HD, + ATA_LBA | ATA_DEVICE(device)); + ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE_EXT); + + } else +#endif + { + ide_outb(device, ATA_DEV_HD, ATA_LBA | + ATA_DEVICE(device) | ((blknr >> 24) & 0xF)); + ide_outb(device, ATA_COMMAND, ATA_CMD_WRITE); + } + + udelay(50); + + /* can't take over 500 ms */ + c = ide_wait(device, IDE_TIME_OUT); + + if ((c & (ATA_STAT_DRQ | ATA_STAT_BUSY | ATA_STAT_ERR)) != + ATA_STAT_DRQ) { + printf("Error (no IRQ) dev %d blk " LBAF + ": status %#02x\n", device, blknr, c); + goto WR_OUT; + } + + ide_output_data(device, buffer, ATA_SECTORWORDS); + c = ide_inb(device, ATA_STATUS); /* clear IRQ */ + ++n; + ++blknr; + buffer += ATA_BLOCKSIZE; + } +WR_OUT: + ide_led(DEVICE_LED(device), 0); /* LED off */ + return n; +} + +#if defined(CONFIG_OF_IDE_FIXUP) +int ide_device_present(int dev) +{ + if (dev >= CONFIG_SYS_IDE_MAXBUS) + return 0; + return ide_dev_desc[dev].type == DEV_TYPE_UNKNOWN ? 0 : 1; +} +#endif + +#ifdef CONFIG_BLK +static const struct blk_ops ide_blk_ops = { + .read = ide_read, + .write = ide_write, +}; + +U_BOOT_DRIVER(ide_blk) = { + .name = "ide_blk", + .id = UCLASS_BLK, + .ops = &ide_blk_ops, +}; +#else +U_BOOT_LEGACY_BLK(ide) = { + .if_typename = "ide", + .if_type = IF_TYPE_IDE, + .max_devs = CONFIG_SYS_IDE_MAXDEVICE, + .desc = ide_dev_desc, +}; +#endif diff --git a/drivers/block/sil680.c b/drivers/block/sil680.c index 3ca64b9..b1db257 100644 --- a/drivers/block/sil680.c +++ b/drivers/block/sil680.c @@ -17,7 +17,7 @@ * incorrect for the target board (e.g. the sequoia board requires 0). * #define CONFIG_SYS_PCI_CACHE_LINE_SIZE 0 * - * #define CONFIG_CMD_IDE + * #define CONFIG_IDE * #undef CONFIG_IDE_8xx_DIRECT * #undef CONFIG_IDE_LED * #undef CONFIG_IDE_RESET diff --git a/drivers/crypto/fsl/Kconfig b/drivers/crypto/fsl/Kconfig index 3188959..181a1e5 100644 --- a/drivers/crypto/fsl/Kconfig +++ b/drivers/crypto/fsl/Kconfig @@ -1,5 +1,7 @@ config FSL_CAAM bool "Freescale Crypto Driver Support" + select SHA_HW_ACCEL + imply CMD_HASH help Enables the Freescale's Cryptographic Accelerator and Assurance Module (CAAM), also known as the SEC version 4 (SEC4). The driver uses diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig deleted file mode 100644 index e69de29..0000000 --- a/drivers/hwmon/Kconfig +++ /dev/null diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile deleted file mode 100644 index b4fb057..0000000 --- a/drivers/hwmon/Makefile +++ /dev/null @@ -1,22 +0,0 @@ -# -# (C) Copyright 2006 -# Wolfgang Denk, DENX Software Engineering, wd@denx.de. -# -# (C) Copyright 2001 -# Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -#ccflags-y += -DDEBUG - -obj-$(CONFIG_DTT_ADM1021) += adm1021.o -obj-$(CONFIG_DTT_ADT7460) += adt7460.o -obj-$(CONFIG_DTT_DS1621) += ds1621.o -obj-$(CONFIG_DTT_DS1722) += ds1722.o -obj-$(CONFIG_DTT_DS1775) += ds1775.o -obj-$(CONFIG_DTT_DS620) += ds620.o -obj-$(CONFIG_DTT_LM63) += lm63.o -obj-$(CONFIG_DTT_LM73) += lm73.o -obj-$(CONFIG_DTT_LM75) += lm75.o -obj-$(CONFIG_DTT_LM81) += lm81.o diff --git a/drivers/hwmon/adm1021.c b/drivers/hwmon/adm1021.c deleted file mode 100644 index 99e942b..0000000 --- a/drivers/hwmon/adm1021.c +++ /dev/null @@ -1,164 +0,0 @@ -/* - * (C) Copyright 2003 - * Murray Jensen, CSIRO-MIT, Murray.Jensen@csiro.au - * - * based on dtt/lm75.c which is ... - * - * (C) Copyright 2001 - * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Analog Devices's ADM1021 - * "Low Cost Microprocessor System Temperature Monitor" - */ - -#include <common.h> - -#include <i2c.h> -#include <dtt.h> - -#define DTT_READ_LOC_VALUE 0x00 -#define DTT_READ_REM_VALUE 0x01 -#define DTT_READ_STATUS 0x02 -#define DTT_READ_CONFIG 0x03 -#define DTT_READ_CONVRATE 0x04 -#define DTT_READ_LOC_HIGHLIM 0x05 -#define DTT_READ_LOC_LOWLIM 0x06 -#define DTT_READ_REM_HIGHLIM 0x07 -#define DTT_READ_REM_LOWLIM 0x08 -#define DTT_READ_DEVID 0xfe - -#define DTT_WRITE_CONFIG 0x09 -#define DTT_WRITE_CONVRATE 0x0a -#define DTT_WRITE_LOC_HIGHLIM 0x0b -#define DTT_WRITE_LOC_LOWLIM 0x0c -#define DTT_WRITE_REM_HIGHLIM 0x0d -#define DTT_WRITE_REM_LOWLIM 0x0e -#define DTT_WRITE_ONESHOT 0x0f - -#define DTT_STATUS_BUSY 0x80 /* 1=ADC Converting */ -#define DTT_STATUS_LHIGH 0x40 /* 1=Local High Temp Limit Tripped */ -#define DTT_STATUS_LLOW 0x20 /* 1=Local Low Temp Limit Tripped */ -#define DTT_STATUS_RHIGH 0x10 /* 1=Remote High Temp Limit Tripped */ -#define DTT_STATUS_RLOW 0x08 /* 1=Remote Low Temp Limit Tripped */ -#define DTT_STATUS_OPEN 0x04 /* 1=Remote Sensor Open-Circuit */ - -#define DTT_CONFIG_ALERT_MASKED 0x80 /* 0=ALERT Enabled, 1=ALERT Masked */ -#define DTT_CONFIG_STANDBY 0x40 /* 0=Run, 1=Standby */ - -#define DTT_ADM1021_DEVID 0x41 - -typedef - struct { - uint i2c_addr:7; /* 7bit i2c chip address */ - uint conv_rate:3; /* conversion rate */ - uint enable_alert:1; /* enable alert output pin */ - uint enable_local:1; /* enable internal temp sensor */ - uint max_local:8; /* internal temp maximum */ - uint min_local:8; /* internal temp minimum */ - uint enable_remote:1; /* enable remote temp sensor */ - uint max_remote:8; /* remote temp maximum */ - uint min_remote:8; /* remote temp minimum */ - } -dtt_cfg_t; - -dtt_cfg_t dttcfg[] = CONFIG_SYS_DTT_ADM1021; - -int -dtt_read (int sensor, int reg) -{ - dtt_cfg_t *dcp = &dttcfg[sensor >> 1]; - uchar data; - - if (i2c_read(dcp->i2c_addr, reg, 1, &data, 1) != 0) - return -1; - - return (int)data; -} /* dtt_read() */ - -int -dtt_write (int sensor, int reg, int val) -{ - dtt_cfg_t *dcp = &dttcfg[sensor >> 1]; - uchar data; - - data = (uchar)(val & 0xff); - - if (i2c_write(dcp->i2c_addr, reg, 1, &data, 1) != 0) - return 1; - - return 0; -} /* dtt_write() */ - -int -dtt_init_one(int sensor) -{ - dtt_cfg_t *dcp = &dttcfg[sensor >> 1]; - int reg, val; - - if (((sensor & 1) == 0 ? dcp->enable_local : dcp->enable_remote) == 0) - return 1; /* sensor is disabled (or rather ignored) */ - - /* - * Setup High Limit register - */ - if ((sensor & 1) == 0) { - reg = DTT_WRITE_LOC_HIGHLIM; - val = dcp->max_local; - } - else { - reg = DTT_WRITE_REM_HIGHLIM; - val = dcp->max_remote; - } - if (dtt_write (sensor, reg, val) != 0) - return 1; - - /* - * Setup Low Limit register - */ - if ((sensor & 1) == 0) { - reg = DTT_WRITE_LOC_LOWLIM; - val = dcp->min_local; - } - else { - reg = DTT_WRITE_REM_LOWLIM; - val = dcp->min_remote; - } - if (dtt_write (sensor, reg, val) != 0) - return 1; - - /* shouldn't hurt if the rest gets done twice */ - - /* - * Setup Conversion Rate register - */ - if (dtt_write (sensor, DTT_WRITE_CONVRATE, dcp->conv_rate) != 0) - return 1; - - /* - * Setup configuraton register - */ - val = 0; /* running */ - if (dcp->enable_alert == 0) - val |= DTT_CONFIG_ALERT_MASKED; /* mask ALERT pin */ - if (dtt_write (sensor, DTT_WRITE_CONFIG, val) != 0) - return 1; - - return 0; -} /* dtt_init_one() */ - -int -dtt_get_temp (int sensor) -{ - signed char val; - - if ((sensor & 1) == 0) - val = dtt_read(sensor, DTT_READ_LOC_VALUE); - else - val = dtt_read(sensor, DTT_READ_REM_VALUE); - - return (int) val; -} /* dtt_get_temp() */ diff --git a/drivers/hwmon/adt7460.c b/drivers/hwmon/adt7460.c deleted file mode 100644 index 9b2c5b6..0000000 --- a/drivers/hwmon/adt7460.c +++ /dev/null @@ -1,73 +0,0 @@ -/* - * (C) Copyright 2008 - * Ricado Ribalda-Universidad Autonoma de Madrid, ricardo.ribalda@gmail.com - * This work has been supported by: QTechnology http://qtec.com/ - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -#define ADT7460_ADDRESS 0x2c -#define ADT7460_INVALID 128 -#define ADT7460_CONFIG 0x40 -#define ADT7460_REM1_TEMP 0x25 -#define ADT7460_LOCAL_TEMP 0x26 -#define ADT7460_REM2_TEMP 0x27 - -int dtt_read(int sensor, int reg) -{ - u8 dir = reg; - u8 data; - - if (i2c_read(ADT7460_ADDRESS, dir, 1, &data, 1) == -1) - return -1; - if (data == ADT7460_INVALID) - return -1; - - return data; -} - -int dtt_write(int sensor, int reg, int val) -{ - u8 dir = reg; - u8 data = val; - - if (i2c_write(ADT7460_ADDRESS, dir, 1, &data, 1) == -1) - return -1; - - return 0; -} - -int dtt_init_one(int sensor) -{ - printf("ADT7460 at I2C address 0x%2x\n", ADT7460_ADDRESS); - - if (dtt_write(0, ADT7460_CONFIG, 1) == -1) { - puts("Error initialiting ADT7460\n"); - return -1; - } - - return 0; -} - -int dtt_get_temp(int sensor) -{ - int aux; - u8 table[] = - { ADT7460_REM1_TEMP, ADT7460_LOCAL_TEMP, ADT7460_REM2_TEMP }; - - if (sensor > 2) { - puts("DTT sensor does not exist\n"); - return -1; - } - - aux = dtt_read(0, table[sensor]); - if (aux == -1) { - puts("DTT temperature read failed\n"); - return -1; - } - - return aux; -} diff --git a/drivers/hwmon/ds1621.c b/drivers/hwmon/ds1621.c deleted file mode 100644 index 66947a6..0000000 --- a/drivers/hwmon/ds1621.c +++ /dev/null @@ -1,155 +0,0 @@ -/* - * (C) Copyright 2001 - * Erik Theisen, Wave 7 Optics, etheisen@mindspring.com. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Dallas Semiconductor's DS1621/1631 Digital Thermometer and Thermostat. - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -/* - * Device code - */ -#define DTT_I2C_DEV_CODE 0x48 /* Dallas Semi's DS1621 */ -#define DTT_READ_TEMP 0xAA -#define DTT_READ_COUNTER 0xA8 -#define DTT_READ_SLOPE 0xA9 -#define DTT_WRITE_START_CONV 0xEE -#define DTT_WRITE_STOP_CONV 0x22 -#define DTT_TEMP_HIGH 0xA1 -#define DTT_TEMP_LOW 0xA2 -#define DTT_CONFIG 0xAC - -/* - * Config register bits - */ -#define DTT_CONFIG_1SHOT 0x01 -#define DTT_CONFIG_POLARITY 0x02 -#define DTT_CONFIG_R0 0x04 /* ds1631 only */ -#define DTT_CONFIG_R1 0x08 /* ds1631 only */ -#define DTT_CONFIG_NVB 0x10 -#define DTT_CONFIG_TLF 0x20 -#define DTT_CONFIG_THF 0x40 -#define DTT_CONFIG_DONE 0x80 - - -int dtt_read(int sensor, int reg) -{ - int dlen; - uchar data[2]; - - /* Calculate sensor address and command */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1621*/ - - /* Prepare to handle 2 byte result */ - switch(reg) { - case DTT_READ_TEMP: - case DTT_TEMP_HIGH: - case DTT_TEMP_LOW: - dlen = 2; - break; - default: - dlen = 1; - } - - /* Now try to read the register */ - if (i2c_read(sensor, reg, 1, data, dlen) != 0) - return 1; - - /* Handle 2 byte result */ - if (dlen == 2) - return (short)((data[0] << 8) | data[1]); - - return (int)data[0]; -} - - -int dtt_write(int sensor, int reg, int val) -{ - int dlen; - uchar data[2]; - - /* Calculate sensor address and register */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); - - /* Handle various data sizes. */ - switch(reg) { - case DTT_READ_TEMP: - case DTT_TEMP_HIGH: - case DTT_TEMP_LOW: - dlen = 2; - data[0] = (char)((val >> 8) & 0xff); /* MSB first */ - data[1] = (char)(val & 0xff); - break; - case DTT_WRITE_START_CONV: - case DTT_WRITE_STOP_CONV: - dlen = 0; - data[0] = (char)0; - data[1] = (char)0; - break; - default: - dlen = 1; - data[0] = (char)(val & 0xff); - } - - /* Write value to device */ - if (i2c_write(sensor, reg, 1, data, dlen) != 0) - return 1; - - /* Poll NV memory busy bit in case write was to register stored in EEPROM */ - while(i2c_reg_read(sensor, DTT_CONFIG) & DTT_CONFIG_NVB) - ; - - return 0; -} - - -int dtt_init_one(int sensor) -{ - int val; - - /* Setup High Temp */ - val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80; - if (dtt_write(sensor, DTT_TEMP_HIGH, val) != 0) - return 1; - - /* Setup Low Temp - hysteresis */ - val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80; - if (dtt_write(sensor, DTT_TEMP_LOW, val) != 0) - return 1; - - /* - * Setup configuraton register - * - * Clear THF & TLF, Reserved = 1, Polarity = Active Low, One Shot = YES - * - * We run in polled mode, since there isn't any way to know if this - * lousy device is ready to provide temperature readings on power up. - */ - val = 0x9; - if (dtt_write(sensor, DTT_CONFIG, val) != 0) - return 1; - - return 0; -} - -int dtt_get_temp(int sensor) -{ - int i; - - /* Start a conversion, may take up to 1 second. */ - dtt_write(sensor, DTT_WRITE_START_CONV, 0); - for (i = 0; i <= 10; i++) { - udelay(100000); - if (dtt_read(sensor, DTT_CONFIG) & DTT_CONFIG_DONE) - break; - } - - return (dtt_read(sensor, DTT_READ_TEMP) / 256); -} diff --git a/drivers/hwmon/ds1722.c b/drivers/hwmon/ds1722.c deleted file mode 100644 index c469588..0000000 --- a/drivers/hwmon/ds1722.c +++ /dev/null @@ -1,137 +0,0 @@ -#include <common.h> -#include <asm/ic/ssi.h> -#include <ds1722.h> - -static void ds1722_select(int dev) -{ - ssi_set_interface(4096, 0, 0, 0); - ssi_chip_select(0); - udelay(1); - ssi_chip_select(dev); - udelay(1); -} - - -u8 ds1722_read(int dev, int addr) -{ - u8 res; - - ds1722_select(dev); - - ssi_tx_byte(addr); - res = ssi_rx_byte(); - - ssi_chip_select(0); - - return res; -} - -void ds1722_write(int dev, int addr, u8 data) -{ - ds1722_select(dev); - - ssi_tx_byte(0x80|addr); - ssi_tx_byte(data); - - ssi_chip_select(0); -} - - -u16 ds1722_temp(int dev, int resolution) -{ - static int useconds[] = { - 75000, 150000, 300000, 600000, 1200000 - }; - char temp; - u16 res; - - - /* set up the desired resulotion ... */ - ds1722_write(dev, 0, 0xe0 | (resolution << 1)); - - /* wait while the chip measures the tremperature */ - udelay(useconds[resolution]); - - res = (temp = ds1722_read(dev, 2)) << 8; - - if (temp < 0) { - temp = (16 - (ds1722_read(dev, 1) >> 4)) & 0x0f; - } else { - temp = (ds1722_read(dev, 1) >> 4); - } - - switch (temp) { - case 0: - /* .0000 */ - break; - case 1: - /* .0625 */ - res |=1; - break; - case 2: - /* .1250 */ - res |=1; - break; - case 3: - /* .1875 */ - res |=2; - break; - case 4: - /* .2500 */ - res |=3; - break; - case 5: - /* .3125 */ - res |=3; - break; - case 6: - /* .3750 */ - res |=4; - break; - case 7: - /* .4375 */ - res |=4; - break; - case 8: - /* .5000 */ - res |=5; - break; - case 9: - /* .5625 */ - res |=6; - break; - case 10: - /* .6250 */ - res |=6; - break; - case 11: - /* .6875 */ - res |=7; - break; - case 12: - /* .7500 */ - res |=8; - break; - case 13: - /* .8125 */ - res |=8; - break; - case 14: - /* .8750 */ - res |=9; - break; - case 15: - /* .9375 */ - res |=9; - break; - } - return res; - -} - -int ds1722_probe(int dev) -{ - u16 temp = ds1722_temp(dev, DS1722_RESOLUTION_12BIT); - printf("%d.%d deg C\n\n", (char)(temp >> 8), temp & 0xff); - return 0; -} diff --git a/drivers/hwmon/ds1775.c b/drivers/hwmon/ds1775.c deleted file mode 100644 index b95b130..0000000 --- a/drivers/hwmon/ds1775.c +++ /dev/null @@ -1,126 +0,0 @@ -/* - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Dallas Semiconductor's DS1775 Digital Thermometer and Thermostat - */ - -#include <common.h> - -#include <i2c.h> -#include <dtt.h> - -#define DTT_I2C_DEV_CODE CONFIG_SYS_I2C_DTT_ADDR /* Dallas Semi's DS1775 device code */ -#define DTT_READ_TEMP 0x0 -#define DTT_CONFIG 0x1 -#define DTT_TEMP_HYST 0x2 -#define DTT_TEMP_OS 0x3 - -int dtt_read(int sensor, int reg) -{ - int dlen; - uchar data[2]; - - /* - * Calculate sensor address and command - */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); /* Calculate addr of ds1775 */ - - /* - * Prepare to handle 2 byte result - */ - if ((reg == DTT_READ_TEMP) || - (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) - dlen = 2; - else - dlen = 1; - - /* - * Now try to read the register - */ - if (i2c_read(sensor, reg, 1, data, dlen) != 0) - return 1; - - /* - * Handle 2 byte result - */ - if (dlen == 2) - return ((int)((short)data[1] + (((short)data[0]) << 8))); - - return (int) data[0]; -} - - -int dtt_write(int sensor, int reg, int val) -{ - int dlen; - uchar data[2]; - - /* - * Calculate sensor address and register - */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); - - /* - * Handle various data sizes - */ - if ((reg == DTT_READ_TEMP) || - (reg == DTT_TEMP_OS) || (reg == DTT_TEMP_HYST)) { - dlen = 2; - data[0] = (char)((val >> 8) & 0xff); /* MSB first */ - data[1] = (char)(val & 0xff); - } else { - dlen = 1; - data[0] = (char)(val & 0xff); - } - - /* - * Write value to device - */ - if (i2c_write(sensor, reg, 1, data, dlen) != 0) - return 1; - - return 0; -} - - -int dtt_init_one(int sensor) -{ - int val; - - /* - * Setup High Temp - */ - val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80; - if (dtt_write(sensor, DTT_TEMP_OS, val) != 0) - return 1; - udelay(50000); /* Max 50ms */ - - /* - * Setup Low Temp - hysteresis - */ - val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80; - if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0) - return 1; - udelay(50000); /* Max 50ms */ - - /* - * Setup configuraton register - * - * Fault Tolerance limits 4, Thermometer resolution bits is 9, - * Polarity = Active Low,continuous conversion mode, Thermostat - * mode is interrupt mode - */ - val = 0xa; - if (dtt_write(sensor, DTT_CONFIG, val) != 0) - return 1; - udelay(50000); /* Max 50ms */ - - return 0; -} - -int dtt_get_temp(int sensor) -{ - return (dtt_read(sensor, DTT_READ_TEMP) / 256); -} diff --git a/drivers/hwmon/ds620.c b/drivers/hwmon/ds620.c deleted file mode 100644 index 1ecc3da..0000000 --- a/drivers/hwmon/ds620.c +++ /dev/null @@ -1,65 +0,0 @@ -/* - * DS620 DTT support - * - * (C) Copyright 2014 3ADEV <http://www.3adev.com> - * Written-by: Albert ARIBAUD <albert.aribaud@3adev.fr> - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * Dallas Semiconductor's DS1621/1631 Digital Thermometer and Thermostat. - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -/* - * Device code - */ -#define DTT_I2C_DEV_CODE 0x48 -#define DTT_START_CONVERT 0x51 -#define DTT_TEMP 0xAA -#define DTT_CONFIG 0xAC - -/* - * Config register MSB bits - */ -#define DTT_CONFIG_1SHOT 0x01 -#define DTT_CONFIG_AUTOC 0x02 -#define DTT_CONFIG_R0 0x04 /* always 1 */ -#define DTT_CONFIG_R1 0x08 /* always 1 */ -#define DTT_CONFIG_TLF 0x10 -#define DTT_CONFIG_THF 0x20 -#define DTT_CONFIG_NVB 0x40 -#define DTT_CONFIG_DONE 0x80 - -#define CHIP(sensor) (DTT_I2C_DEV_CODE + (sensor & 0x07)) - -int dtt_init_one(int sensor) -{ - uint8_t config = DTT_CONFIG_1SHOT - | DTT_CONFIG_R0 - | DTT_CONFIG_R1; - return i2c_write(CHIP(sensor), DTT_CONFIG, 1, &config, 1); -} - -int dtt_get_temp(int sensor) -{ - uint8_t status; - uint8_t temp[2]; - - /* Start a conversion, may take up to 1 second. */ - i2c_write(CHIP(sensor), DTT_START_CONVERT, 1, NULL, 0); - do { - if (i2c_read(CHIP(sensor), DTT_CONFIG, 1, &status, 1)) - /* bail out if I2C error */ - status |= DTT_CONFIG_DONE; - } while (!(status & DTT_CONFIG_DONE)); - if (i2c_read(CHIP(sensor), DTT_TEMP, 1, temp, 2)) - /* bail out if I2C error */ - return -274; /* below absolute zero == error */ - - return ((int16_t)(temp[1] | (temp[0] << 8))) >> 7; -} diff --git a/drivers/hwmon/lm63.c b/drivers/hwmon/lm63.c deleted file mode 100644 index 053c785..0000000 --- a/drivers/hwmon/lm63.c +++ /dev/null @@ -1,160 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Dirk Eibach, Guntermann & Drunck GmbH, eibach@gdsys.de - * based on lm75.c by Bill Hunter - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * National LM63/LM64 Temperature Sensor - * Main difference: LM 64 has -16 Kelvin temperature offset - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -#define DTT_I2C_LM63_ADDR 0x4C /* National LM63 device */ - -#define DTT_READ_TEMP_RMT_MSB 0x01 -#define DTT_CONFIG 0x03 -#define DTT_READ_TEMP_RMT_LSB 0x10 -#define DTT_TACHLIM_LSB 0x48 -#define DTT_TACHLIM_MSB 0x49 -#define DTT_FAN_CONFIG 0x4A -#define DTT_PWM_FREQ 0x4D -#define DTT_PWM_LOOKUP_BASE 0x50 - -struct pwm_lookup_entry { - u8 temp; - u8 pwm; -}; - -/* - * Device code - */ - -int dtt_read(int sensor, int reg) -{ - int dlen; - uchar data[2]; - - /* - * Calculate sensor address and register. - */ - if (!sensor) - sensor = DTT_I2C_LM63_ADDR; /* legacy config */ - - dlen = 1; - - /* - * Now try to read the register. - */ - if (i2c_read(sensor, reg, 1, data, dlen) != 0) - return -1; - - return (int)data[0]; -} /* dtt_read() */ - -int dtt_write(int sensor, int reg, int val) -{ - int dlen; - uchar data[2]; - - /* - * Calculate sensor address and register. - */ - if (!sensor) - sensor = DTT_I2C_LM63_ADDR; /* legacy config */ - - dlen = 1; - data[0] = (char)(val & 0xff); - - /* - * Write value to register. - */ - if (i2c_write(sensor, reg, 1, data, dlen) != 0) - return 1; - - return 0; -} /* dtt_write() */ - -static int is_lm64(int sensor) -{ - return sensor && (sensor != DTT_I2C_LM63_ADDR); -} - -int dtt_init_one(int sensor) -{ - int i; - int val; - - struct pwm_lookup_entry pwm_lookup[] = CONFIG_DTT_PWM_LOOKUPTABLE; - - /* - * Set PWM Frequency to 2.5% resolution - */ - val = 20; - if (dtt_write(sensor, DTT_PWM_FREQ, val) != 0) - return 1; - - /* - * Set Tachometer Limit - */ - val = CONFIG_DTT_TACH_LIMIT; - if (dtt_write(sensor, DTT_TACHLIM_LSB, val & 0xff) != 0) - return 1; - if (dtt_write(sensor, DTT_TACHLIM_MSB, (val >> 8) & 0xff) != 0) - return 1; - - /* - * Make sure PWM Lookup-Table is writeable - */ - if (dtt_write(sensor, DTT_FAN_CONFIG, 0x20) != 0) - return 1; - - /* - * Setup PWM Lookup-Table - */ - for (i = 0; i < ARRAY_SIZE(pwm_lookup); i++) { - int address = DTT_PWM_LOOKUP_BASE + 2 * i; - val = pwm_lookup[i].temp; - if (is_lm64(sensor)) - val -= 16; - if (dtt_write(sensor, address, val) != 0) - return 1; - val = dtt_read(sensor, address); - val = pwm_lookup[i].pwm; - if (dtt_write(sensor, address + 1, val) != 0) - return 1; - } - - /* - * Enable PWM Lookup-Table, PWM Clock 360 kHz, Tachometer Mode 2 - */ - val = 0x02; - if (dtt_write(sensor, DTT_FAN_CONFIG, val) != 0) - return 1; - - /* - * Enable Tach input - */ - val = dtt_read(sensor, DTT_CONFIG) | 0x04; - if (dtt_write(sensor, DTT_CONFIG, val) != 0) - return 1; - - return 0; -} - -int dtt_get_temp(int sensor) -{ - s16 temp = (dtt_read(sensor, DTT_READ_TEMP_RMT_MSB) << 8) - | (dtt_read(sensor, DTT_READ_TEMP_RMT_LSB)); - - if (is_lm64(sensor)) - temp += 16 << 8; - - /* Ignore LSB for now, U-Boot only prints natural numbers */ - return temp >> 8; -} diff --git a/drivers/hwmon/lm73.c b/drivers/hwmon/lm73.c deleted file mode 100644 index c15c751..0000000 --- a/drivers/hwmon/lm73.c +++ /dev/null @@ -1,146 +0,0 @@ -/* - * (C) Copyright 2007-2008 - * Larry Johnson, lrj@acm.org - * - * based on dtt/lm75.c which is ... - * - * (C) Copyright 2001 - * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * National Semiconductor LM73 Temperature Sensor - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -/* - * Device code - */ -#define DTT_I2C_DEV_CODE 0x48 /* National Semi's LM73 device */ -#define DTT_READ_TEMP 0x0 -#define DTT_CONFIG 0x1 -#define DTT_TEMP_HIGH 0x2 -#define DTT_TEMP_LOW 0x3 -#define DTT_CONTROL 0x4 -#define DTT_ID 0x7 - -int dtt_read(int const sensor, int const reg) -{ - int dlen; - uint8_t data[2]; - - /* - * Validate 'reg' param and get register size. - */ - switch (reg) { - case DTT_CONFIG: - case DTT_CONTROL: - dlen = 1; - break; - case DTT_READ_TEMP: - case DTT_TEMP_HIGH: - case DTT_TEMP_LOW: - case DTT_ID: - dlen = 2; - break; - default: - return -1; - } - /* - * Try to read the register at the calculated sensor address. - */ - if (0 != - i2c_read(DTT_I2C_DEV_CODE + (sensor & 0x07), reg, 1, data, dlen)) - return -1; - /* - * Handle 2 byte result. - */ - if (2 == dlen) - return (int)((unsigned)data[0] << 8 | (unsigned)data[1]); - - return (int)data[0]; -} /* dtt_read() */ - -int dtt_write(int const sensor, int const reg, int const val) -{ - int dlen; - uint8_t data[2]; - - /* - * Validate 'reg' param and handle register size - */ - switch (reg) { - case DTT_CONFIG: - case DTT_CONTROL: - dlen = 1; - data[0] = (uint8_t) val; - break; - case DTT_TEMP_HIGH: - case DTT_TEMP_LOW: - dlen = 2; - data[0] = (uint8_t) (val >> 8); /* MSB first */ - data[1] = (uint8_t) val; - break; - default: - return -1; - } - /* - * Write value to register at the calculated sensor address. - */ - return 0 != i2c_write(DTT_I2C_DEV_CODE + (sensor & 0x07), reg, 1, data, - dlen); -} /* dtt_write() */ - -int dtt_init_one(int const sensor) -{ - int val; - - /* - * Validate the Identification register - */ - if (0x0190 != dtt_read(sensor, DTT_ID)) - return -1; - /* - * Setup THIGH (upper-limit) and TLOW (lower-limit) registers - */ - val = CONFIG_SYS_DTT_MAX_TEMP << 7; - if (dtt_write(sensor, DTT_TEMP_HIGH, val)) - return -1; - - val = CONFIG_SYS_DTT_MIN_TEMP << 7; - if (dtt_write(sensor, DTT_TEMP_LOW, val)) - return -1; - /* - * Setup configuraton register - */ - /* config = alert active low, disabled, and reset */ - val = 0x64; - if (dtt_write(sensor, DTT_CONFIG, val)) - return -1; - /* - * Setup control/status register - */ - /* control = temp resolution 0.25C */ - val = 0x00; - if (dtt_write(sensor, DTT_CONTROL, val)) - return -1; - - dtt_read(sensor, DTT_CONTROL); /* clear temperature flags */ - return 0; -} /* dtt_init_one() */ - -int dtt_get_temp(int const sensor) -{ - int const ret = dtt_read(sensor, DTT_READ_TEMP); - - if (ret < 0) { - printf("DTT temperature read failed.\n"); - return 0; - } - return (int)((int16_t) ret + 0x0040) >> 7; -} /* dtt_get_temp() */ diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c deleted file mode 100644 index 462f902..0000000 --- a/drivers/hwmon/lm75.c +++ /dev/null @@ -1,143 +0,0 @@ -/* - * (C) Copyright 2001 - * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * On Semiconductor's LM75 Temperature Sensor - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -/* - * Device code - */ -#if defined(CONFIG_SYS_I2C_DTT_ADDR) -#define DTT_I2C_DEV_CODE CONFIG_SYS_I2C_DTT_ADDR -#else -#define DTT_I2C_DEV_CODE 0x48 /* ON Semi's LM75 device */ -#endif -#define DTT_READ_TEMP 0x0 -#define DTT_CONFIG 0x1 -#define DTT_TEMP_HYST 0x2 -#define DTT_TEMP_SET 0x3 - -int dtt_read(int sensor, int reg) -{ - int dlen; - uchar data[2]; - -#ifdef CONFIG_DTT_AD7414 - /* - * On AD7414 the first value upon bootup is not read correctly. - * This is most likely because of the 800ms update time of the - * temp register in normal update mode. To get current values - * each time we issue the "dtt" command including upon powerup - * we switch into one-short mode. - * - * Issue one-shot mode command - */ - dtt_write(sensor, DTT_CONFIG, 0x64); -#endif - - /* Validate 'reg' param */ - if((reg < 0) || (reg > 3)) - return -1; - - /* Calculate sensor address and register. */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); - - /* Prepare to handle 2 byte result. */ - if ((reg == DTT_READ_TEMP) || - (reg == DTT_TEMP_HYST) || - (reg == DTT_TEMP_SET)) - dlen = 2; - else - dlen = 1; - - /* Now try to read the register. */ - if (i2c_read(sensor, reg, 1, data, dlen) != 0) - return -1; - - /* Handle 2 byte result. */ - if (dlen == 2) - return ((int)((short)data[1] + (((short)data[0]) << 8))); - - return (int)data[0]; -} /* dtt_read() */ - - -int dtt_write(int sensor, int reg, int val) -{ - int dlen; - uchar data[2]; - - /* Validate 'reg' param */ - if ((reg < 0) || (reg > 3)) - return 1; - - /* Calculate sensor address and register. */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x07); - - /* Handle 2 byte values. */ - if ((reg == DTT_READ_TEMP) || - (reg == DTT_TEMP_HYST) || - (reg == DTT_TEMP_SET)) { - dlen = 2; - data[0] = (char)((val >> 8) & 0xff); /* MSB first */ - data[1] = (char)(val & 0xff); - } else { - dlen = 1; - data[0] = (char)(val & 0xff); - } - - /* Write value to register. */ - if (i2c_write(sensor, reg, 1, data, dlen) != 0) - return 1; - - return 0; -} /* dtt_write() */ - - -int dtt_init_one(int sensor) -{ - int val; - - /* Setup TSET ( trip point ) register */ - val = ((CONFIG_SYS_DTT_MAX_TEMP * 2) << 7) & 0xff80; /* trip */ - if (dtt_write(sensor, DTT_TEMP_SET, val) != 0) - return 1; - - /* Setup THYST ( untrip point ) register - Hysteresis */ - val = (((CONFIG_SYS_DTT_MAX_TEMP - CONFIG_SYS_DTT_HYSTERESIS) * 2) << 7) & 0xff80; - if (dtt_write(sensor, DTT_TEMP_HYST, val) != 0) - return 1; - - /* Setup configuraton register */ -#ifdef CONFIG_DTT_AD7414 - /* config = alert active low and disabled */ - val = 0x60; -#else - /* config = 6 sample integration, int mode, active low, and enable */ - val = 0x18; -#endif - if (dtt_write(sensor, DTT_CONFIG, val) != 0) - return 1; - - return 0; -} /* dtt_init_one() */ - -int dtt_get_temp(int sensor) -{ - int const ret = dtt_read(sensor, DTT_READ_TEMP); - - if (ret < 0) { - printf("DTT temperature read failed.\n"); - return 0; - } - return (int)((int16_t) ret / 256); -} /* dtt_get_temp() */ diff --git a/drivers/hwmon/lm81.c b/drivers/hwmon/lm81.c deleted file mode 100644 index bcc8d32..0000000 --- a/drivers/hwmon/lm81.c +++ /dev/null @@ -1,111 +0,0 @@ -/* - * (C) Copyright 2006 - * Heiko Schocher, DENX Software Enginnering <hs@denx.de> - * - * based on dtt/lm75.c which is ... - * - * (C) Copyright 2001 - * Bill Hunter, Wave 7 Optics, williamhunter@mediaone.net - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -/* - * On Semiconductor's LM81 Temperature Sensor - */ - -#include <common.h> -#include <i2c.h> -#include <dtt.h> - -/* - * Device code - */ -#define DTT_I2C_DEV_CODE 0x2c /* ON Semi's LM81 device */ -#define DTT_READ_TEMP 0x27 -#define DTT_CONFIG_TEMP 0x4b -#define DTT_TEMP_MAX 0x39 -#define DTT_TEMP_HYST 0x3a -#define DTT_CONFIG 0x40 - -int dtt_read(int sensor, int reg) -{ - int dlen = 1; - uchar data[2]; - - /* - * Calculate sensor address and register. - */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */ - - /* - * Now try to read the register. - */ - if (i2c_read(sensor, reg, 1, data, dlen) != 0) - return -1; - - return (int)data[0]; -} /* dtt_read() */ - - -int dtt_write(int sensor, int reg, int val) -{ - uchar data; - - /* - * Calculate sensor address and register. - */ - sensor = DTT_I2C_DEV_CODE + (sensor & 0x03); /* calculate address of lm81 */ - - data = (char)(val & 0xff); - - /* - * Write value to register. - */ - if (i2c_write(sensor, reg, 1, &data, 1) != 0) - return 1; - - return 0; -} /* dtt_write() */ - -#define DTT_MANU 0x3e -#define DTT_REV 0x3f -#define DTT_CONFIG 0x40 -#define DTT_ADR 0x48 - -int dtt_init_one(int sensor) -{ - int man; - int adr; - int rev; - - if (dtt_write (sensor, DTT_CONFIG, 0x01) < 0) - return 1; - /* The LM81 needs 400ms to get the correct values ... */ - udelay (400000); - man = dtt_read (sensor, DTT_MANU); - if (man != 0x01) - return 1; - adr = dtt_read (sensor, DTT_ADR); - if (adr < 0) - return 1; - rev = dtt_read (sensor, DTT_REV); - if (rev < 0) - return 1; - - debug ("DTT: Found LM81@%x Rev: %d\n", adr, rev); - return 0; -} /* dtt_init_one() */ - - -#define TEMP_FROM_REG(temp) \ - ((temp)<256?((((temp)&0x1fe) >> 1) * 10) + ((temp) & 1) * 5: \ - ((((temp)&0x1fe) >> 1) -255) * 10 - ((temp) & 1) * 5) \ - -int dtt_get_temp(int sensor) -{ - int val = dtt_read (sensor, DTT_READ_TEMP); - int tmpcnf = dtt_read (sensor, DTT_CONFIG_TEMP); - - return (TEMP_FROM_REG((val << 1) + ((tmpcnf & 0x80) >> 7))) / 10; -} /* dtt_get_temp() */ diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig index 1aae4bc..ecca159 100644 --- a/drivers/misc/Kconfig +++ b/drivers/misc/Kconfig @@ -75,6 +75,14 @@ config CROS_EC_SPI provides a faster and more robust interface than I2C but the bugs are less interesting. +config DS4510 + bool "Enable support for DS4510 CPU supervisor" + help + Enable support for the Maxim DS4510 CPU supervisor. It has an + integrated 64-byte EEPROM, four programmable non-volatile I/O pins + and a configurable timer for the supervisor function. The device is + connected over I2C. + config FSL_SEC_MON bool "Enable FSL SEC_MON Driver" help diff --git a/drivers/misc/ds4510.c b/drivers/misc/ds4510.c index d7c9bd7..55f8936 100644 --- a/drivers/misc/ds4510.c +++ b/drivers/misc/ds4510.c @@ -12,12 +12,7 @@ #include <common.h> #include <i2c.h> #include <command.h> -#include <ds4510.h> - -/* Default to an address that hopefully won't corrupt other i2c devices */ -#ifndef CONFIG_SYS_I2C_DS4510_ADDR -#define CONFIG_SYS_I2C_DS4510_ADDR (~0) -#endif +#include "ds4510.h" enum { DS4510_CMD_INFO, @@ -35,7 +30,7 @@ enum { /* * Write to DS4510, taking page boundaries into account */ -int ds4510_mem_write(uint8_t chip, int offset, uint8_t *buf, int count) +static int ds4510_mem_write(uint8_t chip, int offset, uint8_t *buf, int count) { int wrlen; int i = 0; @@ -64,7 +59,7 @@ int ds4510_mem_write(uint8_t chip, int offset, uint8_t *buf, int count) /* * General read from DS4510 */ -int ds4510_mem_read(uint8_t chip, int offset, uint8_t *buf, int count) +static int ds4510_mem_read(uint8_t chip, int offset, uint8_t *buf, int count) { return i2c_read(chip, offset, 1, buf, count); } @@ -74,7 +69,7 @@ int ds4510_mem_read(uint8_t chip, int offset, uint8_t *buf, int count) * nv = 0 - Writes to SEEPROM registers behave like EEPROM * nv = 1 - Writes to SEEPROM registers behave like SRAM */ -int ds4510_see_write(uint8_t chip, uint8_t nv) +static int ds4510_see_write(uint8_t chip, uint8_t nv) { uint8_t data; @@ -92,7 +87,7 @@ int ds4510_see_write(uint8_t chip, uint8_t nv) /* * Write de-assertion of reset signal delay */ -int ds4510_rstdelay_write(uint8_t chip, uint8_t delay) +static int ds4510_rstdelay_write(uint8_t chip, uint8_t delay) { uint8_t data; @@ -108,7 +103,7 @@ int ds4510_rstdelay_write(uint8_t chip, uint8_t delay) /* * Write pullup characteristics of IO pins */ -int ds4510_pullup_write(uint8_t chip, uint8_t val) +static int ds4510_pullup_write(uint8_t chip, uint8_t val) { val &= DS4510_IO_MASK; @@ -118,7 +113,7 @@ int ds4510_pullup_write(uint8_t chip, uint8_t val) /* * Read pullup characteristics of IO pins */ -int ds4510_pullup_read(uint8_t chip) +static int ds4510_pullup_read(uint8_t chip) { uint8_t val; @@ -131,7 +126,7 @@ int ds4510_pullup_read(uint8_t chip) /* * Write drive level of IO pins */ -int ds4510_gpio_write(uint8_t chip, uint8_t val) +static int ds4510_gpio_write(uint8_t chip, uint8_t val) { uint8_t data; int i; @@ -155,7 +150,7 @@ int ds4510_gpio_write(uint8_t chip, uint8_t val) /* * Read drive level of IO pins */ -int ds4510_gpio_read(uint8_t chip) +static int ds4510_gpio_read(uint8_t chip) { uint8_t data; int val = 0; @@ -175,7 +170,7 @@ int ds4510_gpio_read(uint8_t chip) /* * Read physical level of IO pins */ -int ds4510_gpio_read_val(uint8_t chip) +static int ds4510_gpio_read_val(uint8_t chip) { uint8_t val; @@ -185,8 +180,6 @@ int ds4510_gpio_read_val(uint8_t chip) return val & DS4510_IO_MASK; } -#ifdef CONFIG_CMD_DS4510 -#ifdef CONFIG_CMD_DS4510_INFO /* * Display DS4510 information */ @@ -240,7 +233,6 @@ static int ds4510_info(uint8_t chip) return 0; } -#endif /* CONFIG_CMD_DS4510_INFO */ cmd_tbl_t cmd_ds4510[] = { U_BOOT_CMD_MKENT(device, 3, 0, (void *)DS4510_CMD_DEVICE, "", ""), @@ -248,33 +240,25 @@ cmd_tbl_t cmd_ds4510[] = { U_BOOT_CMD_MKENT(output, 4, 0, (void *)DS4510_CMD_OUTPUT, "", ""), U_BOOT_CMD_MKENT(input, 3, 0, (void *)DS4510_CMD_INPUT, "", ""), U_BOOT_CMD_MKENT(pullup, 4, 0, (void *)DS4510_CMD_PULLUP, "", ""), -#ifdef CONFIG_CMD_DS4510_INFO U_BOOT_CMD_MKENT(info, 2, 0, (void *)DS4510_CMD_INFO, "", ""), -#endif -#ifdef CONFIG_CMD_DS4510_RST U_BOOT_CMD_MKENT(rstdelay, 3, 0, (void *)DS4510_CMD_RSTDELAY, "", ""), -#endif -#ifdef CONFIG_CMD_DS4510_MEM U_BOOT_CMD_MKENT(eeprom, 6, 0, (void *)DS4510_CMD_EEPROM, "", ""), U_BOOT_CMD_MKENT(seeprom, 6, 0, (void *)DS4510_CMD_SEEPROM, "", ""), U_BOOT_CMD_MKENT(sram, 6, 0, (void *)DS4510_CMD_SRAM, "", ""), -#endif }; int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) { - static uint8_t chip = CONFIG_SYS_I2C_DS4510_ADDR; + static uint8_t chip = 0x51; cmd_tbl_t *c; ulong ul_arg2 = 0; ulong ul_arg3 = 0; int tmp; -#ifdef CONFIG_CMD_DS4510_MEM ulong addr; ulong off; ulong cnt; int end; int (*rw_func)(uint8_t, int, uint8_t *, int); -#endif c = find_cmd_tbl(argv[1], cmd_ds4510, ARRAY_SIZE(cmd_ds4510)); @@ -324,15 +308,10 @@ int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) else tmp &= ~(1 << ul_arg2); return ds4510_pullup_write(chip, tmp); -#ifdef CONFIG_CMD_DS4510_INFO case DS4510_CMD_INFO: return ds4510_info(chip); -#endif -#ifdef CONFIG_CMD_DS4510_RST case DS4510_CMD_RSTDELAY: return ds4510_rstdelay_write(chip, ul_arg2); -#endif -#ifdef CONFIG_CMD_DS4510_MEM case DS4510_CMD_EEPROM: end = DS4510_EEPROM + DS4510_EEPROM_SIZE; off = DS4510_EEPROM; @@ -345,13 +324,11 @@ int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) end = DS4510_SRAM + DS4510_SRAM_SIZE; off = DS4510_SRAM; break; -#endif default: /* We should never get here... */ return 1; } -#ifdef CONFIG_CMD_DS4510_MEM /* Only eeprom, seeprom, and sram commands should make it here */ if (strcmp(argv[2], "read") == 0) rw_func = ds4510_mem_read; @@ -370,7 +347,6 @@ int do_ds4510(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) } return rw_func(chip, off, (uint8_t *)addr, cnt); -#endif } U_BOOT_CMD( @@ -378,10 +354,8 @@ U_BOOT_CMD( "ds4510 eeprom/seeprom/sram/gpio access", "device [dev]\n" " - show or set current device address\n" -#ifdef CONFIG_CMD_DS4510_INFO "ds4510 info\n" " - display ds4510 info\n" -#endif "ds4510 output pin 0|1\n" " - set pin low or high-Z\n" "ds4510 input pin\n" @@ -390,12 +364,9 @@ U_BOOT_CMD( " - disable/enable pullup on specified pin\n" "ds4510 nv 0|1\n" " - make gpio and seeprom writes volatile/non-volatile" -#ifdef CONFIG_CMD_DS4510_RST "\n" "ds4510 rstdelay 0-3\n" " - set reset output delay" -#endif -#ifdef CONFIG_CMD_DS4510_MEM "\n" "ds4510 eeprom read addr off cnt\n" "ds4510 eeprom write addr off cnt\n" @@ -406,6 +377,4 @@ U_BOOT_CMD( "ds4510 sram read addr off cnt\n" "ds4510 sram write addr off cnt\n" " - read/write 'cnt' bytes at SRAM offset 'off'" -#endif ); -#endif /* CONFIG_CMD_DS4510 */ diff --git a/drivers/misc/ds4510.h b/drivers/misc/ds4510.h new file mode 100644 index 0000000..a6c6c58 --- /dev/null +++ b/drivers/misc/ds4510.h @@ -0,0 +1,53 @@ +/* + * Copyright 2008 Extreme Engineering Solutions, Inc. + * + * SPDX-License-Identifier: GPL-2.0 + */ + +#ifndef __DS4510_H_ +#define __DS4510_H_ + +/* General defines */ +#define DS4510_NUM_IO 0x04 +#define DS4510_IO_MASK ((1 << DS4510_NUM_IO) - 1) +#define DS4510_EEPROM_PAGE_WRITE_DELAY_MS 20 + +/* EEPROM from 0x00 - 0x39 */ +#define DS4510_EEPROM 0x00 +#define DS4510_EEPROM_SIZE 0x40 +#define DS4510_EEPROM_PAGE_SIZE 0x08 +#define DS4510_EEPROM_PAGE_OFFSET(x) ((x) & (DS4510_EEPROM_PAGE_SIZE - 1)) + +/* SEEPROM from 0xf0 - 0xf7 */ +#define DS4510_SEEPROM 0xf0 +#define DS4510_SEEPROM_SIZE 0x08 + +/* Registers overlapping SEEPROM from 0xf0 - 0xf7 */ +#define DS4510_PULLUP 0xF0 +#define DS4510_PULLUP_DIS 0x00 +#define DS4510_PULLUP_EN 0x01 +#define DS4510_RSTDELAY 0xF1 +#define DS4510_RSTDELAY_MASK 0x03 +#define DS4510_RSTDELAY_125 0x00 +#define DS4510_RSTDELAY_250 0x01 +#define DS4510_RSTDELAY_500 0x02 +#define DS4510_RSTDELAY_1000 0x03 +#define DS4510_IO3 0xF4 +#define DS4510_IO2 0xF5 +#define DS4510_IO1 0xF6 +#define DS4510_IO0 0xF7 + +/* Status configuration registers from 0xf8 - 0xf9*/ +#define DS4510_IO_STATUS 0xF8 +#define DS4510_CFG 0xF9 +#define DS4510_CFG_READY 0x80 +#define DS4510_CFG_TRIP_POINT 0x40 +#define DS4510_CFG_RESET 0x20 +#define DS4510_CFG_SEE 0x10 +#define DS4510_CFG_SWRST 0x08 + +/* SRAM from 0xfa - 0xff */ +#define DS4510_SRAM 0xfa +#define DS4510_SRAM_SIZE 0x06 + +#endif /* __DS4510_H_ */ diff --git a/drivers/pcmcia/marubun_pcmcia.c b/drivers/pcmcia/marubun_pcmcia.c index afd6df6..739d754 100644 --- a/drivers/pcmcia/marubun_pcmcia.c +++ b/drivers/pcmcia/marubun_pcmcia.c @@ -17,7 +17,7 @@ #define CONFIG_PCMCIA #endif -#if defined(CONFIG_CMD_IDE) +#if defined(CONFIG_IDE) #define CONFIG_PCMCIA #endif diff --git a/drivers/pcmcia/mpc8xx_pcmcia.c b/drivers/pcmcia/mpc8xx_pcmcia.c index 1b41e39..dae5560 100644 --- a/drivers/pcmcia/mpc8xx_pcmcia.c +++ b/drivers/pcmcia/mpc8xx_pcmcia.c @@ -9,7 +9,7 @@ #define CONFIG_PCMCIA #endif -#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) +#if defined(CONFIG_IDE) && defined(CONFIG_IDE_8xx_PCCARD) #define CONFIG_PCMCIA #endif diff --git a/drivers/pcmcia/tqm8xx_pcmcia.c b/drivers/pcmcia/tqm8xx_pcmcia.c index 45dcb54..edff50f 100644 --- a/drivers/pcmcia/tqm8xx_pcmcia.c +++ b/drivers/pcmcia/tqm8xx_pcmcia.c @@ -15,7 +15,7 @@ #define CONFIG_PCMCIA #endif -#if defined(CONFIG_CMD_IDE) && defined(CONFIG_IDE_8xx_PCCARD) +#if defined(CONFIG_IDE) && defined(CONFIG_IDE_8xx_PCCARD) #define CONFIG_PCMCIA #endif diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile index 87c3d9c..438681d 100644 --- a/drivers/rtc/Makefile +++ b/drivers/rtc/Makefile @@ -48,7 +48,6 @@ obj-$(CONFIG_RTC_PCF2127) += pcf2127.o obj-$(CONFIG_RTC_PL031) += pl031.o obj-$(CONFIG_RTC_PT7C4338) += pt7c4338.o obj-$(CONFIG_RTC_RS5C372A) += rs5c372.o -obj-$(CONFIG_RTC_RTC4543) += rtc4543.o obj-$(CONFIG_RTC_RV3029) += rv3029.o obj-$(CONFIG_RTC_RX8025) += rx8025.o obj-$(CONFIG_RTC_S3C24X0) += s3c24x0_rtc.o diff --git a/drivers/rtc/rtc4543.c b/drivers/rtc/rtc4543.c deleted file mode 100644 index 8d36edd..0000000 --- a/drivers/rtc/rtc4543.c +++ /dev/null @@ -1,101 +0,0 @@ -/* - * (C) Copyright 2008, 2009 - * Andreas Pfefferle, DENX Software Engineering, ap@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#include <asm/io.h> -#include <common.h> -#include <command.h> -#include <config.h> -#include <rtc.h> -#include <tws.h> - -#if defined(CONFIG_CMD_DATE) - -/* - * Note: The acrobatics below is due to the hideously ingenius idea of - * the chip designers. As the chip does not allow register - * addressing, all values need to be read and written in one go. Sure - * enough, the 'wday' field (0-6) is transferred using the economic - * number of 4 bits right in the middle of the packet..... - */ - -int rtc_get(struct rtc_time *tm) -{ - int rel = 0; - uchar buffer[7]; - - memset(buffer, 0, 7); - - /* Read 52 bits into our buffer */ - tws_read(buffer, 52); - - tm->tm_sec = bcd2bin( buffer[0] & 0x7F); - tm->tm_min = bcd2bin( buffer[1] & 0x7F); - tm->tm_hour = bcd2bin( buffer[2] & 0x3F); - tm->tm_wday = bcd2bin( buffer[3] & 0x07); - tm->tm_mday = bcd2bin((buffer[3] & 0xF0) >> 4 | (buffer[4] & 0x0F) << 4); - tm->tm_mon = bcd2bin((buffer[4] & 0x30) >> 4 | (buffer[5] & 0x0F) << 4); - tm->tm_year = bcd2bin((buffer[5] & 0xF0) >> 4 | (buffer[6] & 0x0F) << 4) + 2000; - tm->tm_yday = 0; - tm->tm_isdst = 0; - - if (tm->tm_sec & 0x80) { - puts("### Warning: RTC Low Voltage - date/time not reliable\n"); - rel = -1; - } - - 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; -} - -int rtc_set(struct rtc_time *tm) -{ - uchar buffer[7]; - uchar tmp; - - debug("Set 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); - - memset(buffer, 0, 7); - buffer[0] = bin2bcd(tm->tm_sec); - buffer[1] = bin2bcd(tm->tm_min); - buffer[2] = bin2bcd(tm->tm_hour); - buffer[3] = bin2bcd(tm->tm_wday); - tmp = bin2bcd(tm->tm_mday); - buffer[3] |= (tmp & 0x0F) << 4; - buffer[4] = (tmp & 0xF0) >> 4; - tmp = bin2bcd(tm->tm_mon); - buffer[4] |= (tmp & 0x0F) << 4; - buffer[5] = (tmp & 0xF0) >> 4; - tmp = bin2bcd(tm->tm_year % 100); - buffer[5] |= (tmp & 0x0F) << 4; - buffer[6] = (tmp & 0xF0) >> 4; - - /* Write the resulting 52 bits to device */ - tws_write(buffer, 52); - - return 0; -} - -void rtc_reset(void) -{ - struct rtc_time tmp; - - tmp.tm_sec = 0; - tmp.tm_min = 0; - tmp.tm_hour = 0; - tmp.tm_wday = 4; - tmp.tm_mday = 1; - tmp.tm_mon = 1; - tmp.tm_year = 2000; - rtc_set(&tmp); -} - -#endif diff --git a/drivers/timer/Kconfig b/drivers/timer/Kconfig index e038523..17e7dfe 100644 --- a/drivers/timer/Kconfig +++ b/drivers/timer/Kconfig @@ -74,4 +74,16 @@ config ARC_TIMER usually at least one of them exists. Either of them is supported in U-Boot. +config AG101P_TIMER + bool "AG101P timer support" + depends on TIMER && NDS32 + help + Select this to enable a timer for AG01P devices. + +config AE3XX_TIMER + bool "AE3XX timer support" + depends on TIMER && NDS32 + help + Select this to enable a timer for AE3XX devices. + endmenu diff --git a/drivers/timer/Makefile b/drivers/timer/Makefile index bfe65fc..ced7bd6 100644 --- a/drivers/timer/Makefile +++ b/drivers/timer/Makefile @@ -12,3 +12,5 @@ obj-$(CONFIG_OMAP_TIMER) += omap-timer.o obj-$(CONFIG_AST_TIMER) += ast_timer.o obj-$(CONFIG_STI_TIMER) += sti-timer.o obj-$(CONFIG_ARC_TIMER) += arc_timer.o +obj-$(CONFIG_AG101P_TIMER) += ag101p_timer.o +obj-$(CONFIG_AE3XX_TIMER) += ae3xx_timer.o diff --git a/drivers/timer/ae3xx_timer.c b/drivers/timer/ae3xx_timer.c new file mode 100644 index 0000000..7ccb3eb --- /dev/null +++ b/drivers/timer/ae3xx_timer.c @@ -0,0 +1,117 @@ +/* + * Andestech ATCPIT100 timer driver + * + * (C) Copyright 2016 + * Rick Chen, NDS32 Software Engineering, rick@andestech.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> +#include <linux/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +#define REG32_TMR(x) (*(unsigned long *) ((plat->regs) + (x>>2))) + +/* + * Definition of register offsets + */ + +/* ID and Revision Register */ +#define ID_REV 0x0 + +/* Configuration Register */ +#define CFG 0x10 + +/* Interrupt Enable Register */ +#define INT_EN 0x14 +#define CH_INT_EN(c , i) ((1<<i)<<(4*c)) + +/* Interrupt Status Register */ +#define INT_STA 0x18 +#define CH_INT_STA(c , i) ((1<<i)<<(4*c)) + +/* Channel Enable Register */ +#define CH_EN 0x1C +#define CH_TMR_EN(c , t) ((1<<t)<<(4*c)) + +/* Ch n Control REgister */ +#define CH_CTL(n) (0x20+0x10*n) +/* Channel clock source , bit 3 , 0:External clock , 1:APB clock */ +#define APB_CLK (1<<3) +/* Channel mode , bit 0~2 */ +#define TMR_32 1 +#define TMR_16 2 +#define TMR_8 3 +#define PWM 4 + +#define CH_REL(n) (0x24+0x10*n) +#define CH_CNT(n) (0x28+0x10*n) + +struct atctmr_timer_regs { + u32 id_rev; /* 0x00 */ + u32 reservd[3]; /* 0x04 ~ 0x0c */ + u32 cfg; /* 0x10 */ + u32 int_en; /* 0x14 */ + u32 int_st; /* 0x18 */ + u32 ch_en; /* 0x1c */ + u32 ch0_ctrl; /* 0x20 */ + u32 ch0_reload; /* 0x24 */ + u32 ch0_cntr; /* 0x28 */ + u32 reservd1; /* 0x2c */ + u32 ch1_ctrl; /* 0x30 */ + u32 ch1_reload; /* 0x34 */ + u32 int_mask; /* 0x38 */ +}; + +struct atftmr_timer_platdata { + unsigned long *regs; +}; + +static int atftmr_timer_get_count(struct udevice *dev, u64 *count) +{ + struct atftmr_timer_platdata *plat = dev->platdata; + u32 val; + val = ~(REG32_TMR(CH_CNT(1))+0xffffffff); + *count = timer_conv_64(val); + return 0; +} + +static int atctmr_timer_probe(struct udevice *dev) +{ + struct atftmr_timer_platdata *plat = dev->platdata; + REG32_TMR(CH_REL(1)) = 0xffffffff; + REG32_TMR(CH_CTL(1)) = APB_CLK|TMR_32; + REG32_TMR(CH_EN) |= CH_TMR_EN(1 , 0); + return 0; +} + +static int atctme_timer_ofdata_to_platdata(struct udevice *dev) +{ + struct atftmr_timer_platdata *plat = dev_get_platdata(dev); + plat->regs = map_physmem(dev_get_addr(dev) , 0x100 , MAP_NOCACHE); + return 0; +} + +static const struct timer_ops ag101p_timer_ops = { + .get_count = atftmr_timer_get_count, +}; + +static const struct udevice_id ag101p_timer_ids[] = { + { .compatible = "andestech,atcpit100" }, + {} +}; + +U_BOOT_DRIVER(altera_timer) = { + .name = "ae3xx_timer", + .id = UCLASS_TIMER, + .of_match = ag101p_timer_ids, + .ofdata_to_platdata = atctme_timer_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata), + .probe = atctmr_timer_probe, + .ops = &ag101p_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/timer/ag101p_timer.c b/drivers/timer/ag101p_timer.c new file mode 100644 index 0000000..163402f --- /dev/null +++ b/drivers/timer/ag101p_timer.c @@ -0,0 +1,122 @@ +/* + * Andestech ATFTMR010 timer driver + * + * (C) Copyright 2016 + * Rick Chen, NDS32 Software Engineering, rick@andestech.com + * + * SPDX-License-Identifier: GPL-2.0+ + */ +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <timer.h> +#include <linux/io.h> + +DECLARE_GLOBAL_DATA_PTR; + +/* + * Timer Control Register + */ +#define T3_UPDOWN (1 << 11) +#define T2_UPDOWN (1 << 10) +#define T1_UPDOWN (1 << 9) +#define T3_OFENABLE (1 << 8) +#define T3_CLOCK (1 << 7) +#define T3_ENABLE (1 << 6) +#define T2_OFENABLE (1 << 5) +#define T2_CLOCK (1 << 4) +#define T2_ENABLE (1 << 3) +#define T1_OFENABLE (1 << 2) +#define T1_CLOCK (1 << 1) +#define T1_ENABLE (1 << 0) + +/* + * Timer Interrupt State & Mask Registers + */ +#define T3_OVERFLOW (1 << 8) +#define T3_MATCH2 (1 << 7) +#define T3_MATCH1 (1 << 6) +#define T2_OVERFLOW (1 << 5) +#define T2_MATCH2 (1 << 4) +#define T2_MATCH1 (1 << 3) +#define T1_OVERFLOW (1 << 2) +#define T1_MATCH2 (1 << 1) +#define T1_MATCH1 (1 << 0) + +struct atftmr_timer_regs { + u32 t1_counter; /* 0x00 */ + u32 t1_load; /* 0x04 */ + u32 t1_match1; /* 0x08 */ + u32 t1_match2; /* 0x0c */ + u32 t2_counter; /* 0x10 */ + u32 t2_load; /* 0x14 */ + u32 t2_match1; /* 0x18 */ + u32 t2_match2; /* 0x1c */ + u32 t3_counter; /* 0x20 */ + u32 t3_load; /* 0x24 */ + u32 t3_match1; /* 0x28 */ + u32 t3_match2; /* 0x2c */ + u32 cr; /* 0x30 */ + u32 int_state; /* 0x34 */ + u32 int_mask; /* 0x38 */ +}; + +struct atftmr_timer_platdata { + struct atftmr_timer_regs *regs; +}; + +static int atftmr_timer_get_count(struct udevice *dev, u64 *count) +{ + struct atftmr_timer_platdata *plat = dev->platdata; + struct atftmr_timer_regs *const regs = plat->regs; + u32 val; + val = readl(®s->t3_counter); + *count = timer_conv_64(val); + return 0; +} + +static int atftmr_timer_probe(struct udevice *dev) +{ + struct atftmr_timer_platdata *plat = dev->platdata; + struct atftmr_timer_regs *const regs = plat->regs; + u32 cr; + writel(0, ®s->t3_load); + writel(0, ®s->t3_counter); + writel(TIMER_LOAD_VAL, ®s->t3_match1); + writel(TIMER_LOAD_VAL, ®s->t3_match2); + /* disable interrupts */ + writel(T3_MATCH1|T3_MATCH2|T3_OVERFLOW , ®s->int_mask); + cr = readl(®s->cr); + cr |= (T3_ENABLE|T3_UPDOWN); + writel(cr, ®s->cr); + return 0; +} + +static int atftme_timer_ofdata_to_platdata(struct udevice *dev) +{ + struct atftmr_timer_platdata *plat = dev_get_platdata(dev); + plat->regs = map_physmem(dev_get_addr(dev), + sizeof(struct atftmr_timer_regs), + MAP_NOCACHE); + return 0; +} + +static const struct timer_ops ag101p_timer_ops = { + .get_count = atftmr_timer_get_count, +}; + +static const struct udevice_id ag101p_timer_ids[] = { + { .compatible = "andestech,attmr010" }, + {} +}; + +U_BOOT_DRIVER(altera_timer) = { + .name = "ag101p_timer", + .id = UCLASS_TIMER, + .of_match = ag101p_timer_ids, + .ofdata_to_platdata = atftme_timer_ofdata_to_platdata, + .platdata_auto_alloc_size = sizeof(struct atftmr_timer_platdata), + .probe = atftmr_timer_probe, + .ops = &ag101p_timer_ops, + .flags = DM_FLAG_PRE_RELOC, +}; diff --git a/drivers/twserial/Makefile b/drivers/twserial/Makefile deleted file mode 100644 index 7cc7c4d..0000000 --- a/drivers/twserial/Makefile +++ /dev/null @@ -1,8 +0,0 @@ -# -# (C) Copyright 2009 -# Detlev Zundel, DENX Software Engineering, dzu@denx.de. -# -# SPDX-License-Identifier: GPL-2.0+ -# - -obj-$(CONFIG_SOFT_TWS) += soft_tws.o diff --git a/drivers/twserial/soft_tws.c b/drivers/twserial/soft_tws.c deleted file mode 100644 index d0bf93d..0000000 --- a/drivers/twserial/soft_tws.c +++ /dev/null @@ -1,94 +0,0 @@ -/* - * (C) Copyright 2009 - * Detlev Zundel, DENX Software Engineering, dzu@denx.de. - * - * SPDX-License-Identifier: GPL-2.0+ - */ - -#define TWS_IMPLEMENTATION -#include <common.h> - -/*=====================================================================*/ -/* Public Functions */ -/*=====================================================================*/ - -/*----------------------------------------------------------------------- - * Read bits - */ -int tws_read(uchar *buffer, int len) -{ - int rem = len; - uchar accu, shift; - - debug("tws_read: buffer %p len %d\n", buffer, len); - - /* Configure the data pin for input */ - tws_data_config_output(0); - - /* Disable WR, i.e. setup a read */ - tws_wr(0); - udelay(1); - - /* Rise CE */ - tws_ce(1); - udelay(1); - - for (; rem > 0; ) { - for (shift = 0, accu = 0; - (rem > 0) && (shift < 8); - rem--, shift++) { - tws_clk(1); - udelay(10); - accu |= (tws_data_read() << shift); /* LSB first */ - tws_clk(0); - udelay(10); - } - *buffer++ = accu; - } - - /* Lower CE */ - tws_ce(0); - - return len - rem; -} - - -/*----------------------------------------------------------------------- - * Write bits - */ -int tws_write(uchar *buffer, int len) -{ - int rem = len; - uchar accu, shift; - - debug("tws_write: buffer %p len %d\n", buffer, len); - - /* Configure the data pin for output */ - tws_data_config_output(1); - - /* Enable WR, i.e. setup a write */ - tws_wr(1); - udelay(1); - - /* Rise CE */ - tws_ce(1); - udelay(1); - - for (; rem > 0; ) { - for (shift = 0, accu = *buffer++; - (rem > 0) && (shift < 8); - rem--, shift++) { - tws_data(accu & 0x01); /* LSB first */ - tws_clk(1); - udelay(10); - tws_clk(0); - udelay(10); - accu >>= 1; - } - } - - /* Lower CE */ - tws_ce(0); - - return len - rem; -} diff --git a/drivers/usb/eth/mcs7830.c b/drivers/usb/eth/mcs7830.c index 9d6cf8c..4abef5d 100644 --- a/drivers/usb/eth/mcs7830.c +++ b/drivers/usb/eth/mcs7830.c @@ -622,10 +622,12 @@ static int mcs7830_recv(struct eth_device *eth) int len; len = mcs7830_recv_common(ueth, buf); - if (len <= 0) + if (len >= 0) { net_process_received_packet(buf, len); + return 0; + } - return 0; + return len; } /* diff --git a/drivers/usb/host/Kconfig b/drivers/usb/host/Kconfig index 9a67e43..b824eec 100644 --- a/drivers/usb/host/Kconfig +++ b/drivers/usb/host/Kconfig @@ -133,6 +133,14 @@ config USB_EHCI_MSM This driver supports combination of Chipidea USB controller and Synapsys USB PHY in host mode only. +config USB_EHCI_RCAR_GEN3 + bool "Support for Renesas RCar M3/H3 EHCI USB controller" + depends on RCAR_GEN3 + default y + ---help--- + Enables support for the on-chip EHCI controller on Renesas + R8A7795 and R8A7796 SoCs. + config USB_EHCI_ZYNQ bool "Support for Xilinx Zynq on-chip EHCI USB controller" depends on ARCH_ZYNQ diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile index bf354fe..4ece0a2 100644 --- a/drivers/usb/host/Makefile +++ b/drivers/usb/host/Makefile @@ -51,6 +51,7 @@ obj-$(CONFIG_USB_EHCI_TEGRA) += ehci-tegra.o obj-$(CONFIG_USB_EHCI_VCT) += ehci-vct.o obj-$(CONFIG_USB_EHCI_VF) += ehci-vf.o obj-$(CONFIG_USB_EHCI_RMOBILE) += ehci-rmobile.o +obj-$(CONFIG_USB_EHCI_RCAR_GEN3) += ehci-rcar_gen3.o obj-$(CONFIG_USB_EHCI_ZYNQ) += ehci-zynq.o # xhci diff --git a/drivers/usb/host/ehci-rcar_gen3.c b/drivers/usb/host/ehci-rcar_gen3.c new file mode 100644 index 0000000..525e7f3 --- /dev/null +++ b/drivers/usb/host/ehci-rcar_gen3.c @@ -0,0 +1,106 @@ +/* + * drivers/usb/host/ehci-rcar_gen3. + * This file is EHCI HCD (Host Controller Driver) for USB. + * + * Copyright (C) 2015-2017 Renesas Electronics Corporation + * + * SPDX-License-Identifier: GPL-2.0+ + */ + +#include <common.h> +#include <errno.h> +#include <wait_bit.h> +#include <asm/io.h> +#include <usb/ehci-ci.h> +#include "ehci.h" + +#define RCAR_GEN3_USB_BASE(n) (0xEE080000 + ((n) * 0x20000)) + +#define EHCI_USBCMD 0x120 + +#define CORE_SPD_RSM_TIMSET 0x30c +#define CORE_OC_TIMSET 0x310 + +/* Register offset */ +#define AHB_OFFSET 0x200 + +#define BASE_HSUSB 0xE6590000 +#define REG_LPSTS (BASE_HSUSB + 0x0102) /* 16bit */ +#define SUSPM 0x4000 +#define SUSPM_NORMAL BIT(14) +#define REG_UGCTRL2 (BASE_HSUSB + 0x0184) /* 32bit */ +#define USB0SEL 0x00000030 +#define USB0SEL_EHCI 0x00000010 + +#define SMSTPCR7 0xE615014C +#define SMSTPCR700 BIT(0) /* EHCI3 */ +#define SMSTPCR701 BIT(1) /* EHCI2 */ +#define SMSTPCR702 BIT(2) /* EHCI1 */ +#define SMSTPCR703 BIT(3) /* EHCI0 */ +#define SMSTPCR704 BIT(4) /* HSUSB */ + +#define AHB_PLL_RST BIT(1) + +#define USBH_INTBEN BIT(2) +#define USBH_INTAEN BIT(1) + +#define AHB_INT_ENABLE 0x200 +#define AHB_USBCTR 0x20c + +int ehci_hcd_stop(int index) +{ +#if defined(CONFIG_R8A7795) + const u32 mask = SMSTPCR703 | SMSTPCR702 | SMSTPCR701 | SMSTPCR700; +#else + const u32 mask = SMSTPCR703 | SMSTPCR702; +#endif + const u32 base = RCAR_GEN3_USB_BASE(index); + int ret; + + /* Reset EHCI */ + setbits_le32((uintptr_t)(base + EHCI_USBCMD), CMD_RESET); + ret = wait_for_bit("ehci-rcar", (void *)(uintptr_t)base + EHCI_USBCMD, + CMD_RESET, false, 10, true); + if (ret) { + printf("ehci-rcar: reset failed (index=%i, ret=%i).\n", + index, ret); + } + + setbits_le32(SMSTPCR7, BIT(3 - index)); + + if ((readl(SMSTPCR7) & mask) == mask) + setbits_le32(SMSTPCR7, SMSTPCR704); + + return 0; +} + +int ehci_hcd_init(int index, enum usb_init_type init, + struct ehci_hccr **hccr, struct ehci_hcor **hcor) +{ + const void __iomem *base = + (void __iomem *)(uintptr_t)RCAR_GEN3_USB_BASE(index); + struct usb_ehci *ehci = (struct usb_ehci *)(uintptr_t)base; + + clrbits_le32(SMSTPCR7, BIT(3 - index)); + clrbits_le32(SMSTPCR7, SMSTPCR704); + + *hccr = (struct ehci_hccr *)((uintptr_t)&ehci->caplength); + *hcor = (struct ehci_hcor *)((uintptr_t)*hccr + + HC_LENGTH(ehci_readl(&(*hccr)->cr_capbase))); + + /* Enable interrupt */ + setbits_le32(base + AHB_INT_ENABLE, USBH_INTBEN | USBH_INTAEN); + writel(0x014e029b, base + CORE_SPD_RSM_TIMSET); + writel(0x000209ab, base + CORE_OC_TIMSET); + + /* Choice USB0SEL */ + clrsetbits_le32(REG_UGCTRL2, USB0SEL, USB0SEL_EHCI); + + /* Clock & Reset */ + clrbits_le32(base + AHB_USBCTR, AHB_PLL_RST); + + /* low power status */ + clrsetbits_le16(REG_LPSTS, SUSPM, SUSPM_NORMAL); + + return 0; +} |