Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v3.9-rc2 167 lines 4.6 kB view raw
1/* 2 * EZ-USB specific functions used by some of the USB to Serial drivers. 3 * 4 * Copyright (C) 1999 - 2002 Greg Kroah-Hartman (greg@kroah.com) 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License version 8 * 2 as published by the Free Software Foundation. 9 */ 10 11#include <linux/kernel.h> 12#include <linux/init.h> 13#include <linux/slab.h> 14#include <linux/module.h> 15#include <linux/usb.h> 16#include <linux/firmware.h> 17#include <linux/ihex.h> 18#include <linux/usb/ezusb.h> 19 20struct ezusb_fx_type { 21 /* EZ-USB Control and Status Register. Bit 0 controls 8051 reset */ 22 unsigned short cpucs_reg; 23 unsigned short max_internal_adress; 24}; 25 26static struct ezusb_fx_type ezusb_fx1 = { 27 .cpucs_reg = 0x7F92, 28 .max_internal_adress = 0x1B3F, 29}; 30 31/* Commands for writing to memory */ 32#define WRITE_INT_RAM 0xA0 33#define WRITE_EXT_RAM 0xA3 34 35static int ezusb_writememory(struct usb_device *dev, int address, 36 unsigned char *data, int length, __u8 request) 37{ 38 int result; 39 unsigned char *transfer_buffer; 40 41 if (!dev) 42 return -ENODEV; 43 44 transfer_buffer = kmemdup(data, length, GFP_KERNEL); 45 if (!transfer_buffer) { 46 dev_err(&dev->dev, "%s - kmalloc(%d) failed.\n", 47 __func__, length); 48 return -ENOMEM; 49 } 50 result = usb_control_msg(dev, usb_sndctrlpipe(dev, 0), request, 51 USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE, 52 address, 0, transfer_buffer, length, 3000); 53 54 kfree(transfer_buffer); 55 return result; 56} 57 58static int ezusb_set_reset(struct usb_device *dev, unsigned short cpucs_reg, 59 unsigned char reset_bit) 60{ 61 int response = ezusb_writememory(dev, cpucs_reg, &reset_bit, 1, WRITE_INT_RAM); 62 if (response < 0) 63 dev_err(&dev->dev, "%s-%d failed: %d\n", 64 __func__, reset_bit, response); 65 return response; 66} 67 68int ezusb_fx1_set_reset(struct usb_device *dev, unsigned char reset_bit) 69{ 70 return ezusb_set_reset(dev, ezusb_fx1.cpucs_reg, reset_bit); 71} 72EXPORT_SYMBOL_GPL(ezusb_fx1_set_reset); 73 74static int ezusb_ihex_firmware_download(struct usb_device *dev, 75 struct ezusb_fx_type fx, 76 const char *firmware_path) 77{ 78 int ret = -ENOENT; 79 const struct firmware *firmware = NULL; 80 const struct ihex_binrec *record; 81 82 if (request_ihex_firmware(&firmware, firmware_path, 83 &dev->dev)) { 84 dev_err(&dev->dev, 85 "%s - request \"%s\" failed\n", 86 __func__, firmware_path); 87 goto out; 88 } 89 90 ret = ezusb_set_reset(dev, fx.cpucs_reg, 0); 91 if (ret < 0) 92 goto out; 93 94 record = (const struct ihex_binrec *)firmware->data; 95 for (; record; record = ihex_next_binrec(record)) { 96 if (be32_to_cpu(record->addr) > fx.max_internal_adress) { 97 ret = ezusb_writememory(dev, be32_to_cpu(record->addr), 98 (unsigned char *)record->data, 99 be16_to_cpu(record->len), WRITE_EXT_RAM); 100 if (ret < 0) { 101 dev_err(&dev->dev, "%s - ezusb_writememory " 102 "failed writing internal memory " 103 "(%d %04X %p %d)\n", __func__, ret, 104 be32_to_cpu(record->addr), record->data, 105 be16_to_cpu(record->len)); 106 goto out; 107 } 108 } 109 } 110 111 ret = ezusb_set_reset(dev, fx.cpucs_reg, 1); 112 if (ret < 0) 113 goto out; 114 record = (const struct ihex_binrec *)firmware->data; 115 for (; record; record = ihex_next_binrec(record)) { 116 if (be32_to_cpu(record->addr) <= fx.max_internal_adress) { 117 ret = ezusb_writememory(dev, be32_to_cpu(record->addr), 118 (unsigned char *)record->data, 119 be16_to_cpu(record->len), WRITE_INT_RAM); 120 if (ret < 0) { 121 dev_err(&dev->dev, "%s - ezusb_writememory " 122 "failed writing external memory " 123 "(%d %04X %p %d)\n", __func__, ret, 124 be32_to_cpu(record->addr), record->data, 125 be16_to_cpu(record->len)); 126 goto out; 127 } 128 } 129 } 130 ret = ezusb_set_reset(dev, fx.cpucs_reg, 0); 131out: 132 release_firmware(firmware); 133 return ret; 134} 135 136int ezusb_fx1_ihex_firmware_download(struct usb_device *dev, 137 const char *firmware_path) 138{ 139 return ezusb_ihex_firmware_download(dev, ezusb_fx1, firmware_path); 140} 141EXPORT_SYMBOL_GPL(ezusb_fx1_ihex_firmware_download); 142 143#if 0 144/* 145 * Once someone one needs these fx2 functions, uncomment them 146 * and add them to ezusb.h and all should be good. 147 */ 148static struct ezusb_fx_type ezusb_fx2 = { 149 .cpucs_reg = 0xE600, 150 .max_internal_adress = 0x3FFF, 151}; 152 153int ezusb_fx2_set_reset(struct usb_device *dev, unsigned char reset_bit) 154{ 155 return ezusb_set_reset(dev, ezusb_fx2.cpucs_reg, reset_bit); 156} 157EXPORT_SYMBOL_GPL(ezusb_fx2_set_reset); 158 159int ezusb_fx2_ihex_firmware_download(struct usb_device *dev, 160 const char *firmware_path) 161{ 162 return ezusb_ihex_firmware_download(dev, ezusb_fx2, firmware_path); 163} 164EXPORT_SYMBOL_GPL(ezusb_fx2_ihex_firmware_download); 165#endif 166 167MODULE_LICENSE("GPL");