int BcmSpiReserveSlave2(int busNum, int slaveId, int maxFreq, int spiMode, int ctrlState) { struct spi_master * pSpiMaster; struct spi_driver * pSpiDriver; if ( slaveId > 7 ) { return SPI_STATUS_ERR; } if ( LEG_SPI_BUS_NUM == busNum ) { #ifndef SPI return( SPI_STATUS_ERR ); #else if ( NULL != bcmLegSpiDevices[slaveId] ) { printk(KERN_ERR "BcmSpiReserveSlave - slaveId %d, already registerd\n", slaveId); return( SPI_STATUS_ERR ); } bcmLegSpiDevInfo[slaveId].max_speed_hz = maxFreq; bcmLegSpiDevInfo[slaveId].controller_data = (void *)ctrlState; bcmLegSpiDevInfo[slaveId].mode = spiMode; pSpiMaster = spi_busnum_to_master( busNum ); bcmLegSpiDevices[slaveId] = spi_new_device(pSpiMaster, &bcmLegSpiDevInfo[slaveId]); pSpiDriver = &bcmLegSpiDevDrv[slaveId]; #endif } else if ( HS_SPI_BUS_NUM == busNum ) { #ifndef HS_SPI return( SPI_STATUS_ERR ); #else if ( NULL != bcmHSSpiDevices[slaveId] ) { printk(KERN_ERR "BcmSpiReserveSlave - slaveId %d, already registerd\n", slaveId); return( SPI_STATUS_ERR ); } bcmHSSpiDevInfo[slaveId].max_speed_hz = maxFreq; bcmHSSpiDevInfo[slaveId].controller_data = (void *)ctrlState; bcmHSSpiDevInfo[slaveId].mode = spiMode; pSpiMaster = spi_busnum_to_master( busNum ); bcmHSSpiDevices[slaveId] = spi_new_device(pSpiMaster, &bcmHSSpiDevInfo[slaveId]); pSpiDriver = &bcmHSSpiDevDrv[slaveId]; #endif } else return( SPI_STATUS_ERR ); /* register the SPI driver */ spi_register_driver(pSpiDriver); return 0; }
static int __devinit xilinx_spi_probe(struct platform_device *dev) { struct xspi_platform_data *pdata; struct resource *r; int irq; struct spi_master *master; u8 i; pdata = dev->dev.platform_data; if (!pdata) return -ENODEV; r = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!r) return -ENODEV; irq = platform_get_irq(dev, 0); if (irq < 0) return -ENXIO; master = xilinx_spi_init(&dev->dev, r, irq, dev->id); if (!master) return -ENODEV; for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); platform_set_drvdata(dev, master); return 0; }
static int __init low_speed_spidev_module_init(void) { struct spi_master *master; int err; pr_info("module init\n"); err = -ENODEV; master = spi_busnum_to_master(LOW_SPEED_SPIDEV_SPI_BUS); pr_info("master=%p\n", master); if (!master) goto out; dev = spi_new_device(master, &cal_spi_board_info); pr_info("dev=%p\n", dev); if (!dev) goto out; pr_info("spidev registered\n"); err = 0; out: if (err) pr_err("Failed to register SPI device\n"); return err; }
struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, struct spi_master *master, struct spi_board_info *info) { struct v4l2_subdev *sd = NULL; struct spi_device *spi = NULL; BUG_ON(!v4l2_dev); if (info->modalias) request_module(info->modalias); spi = spi_new_device(master, info); if (spi == NULL || spi->dev.driver == NULL) goto error; if (!try_module_get(spi->dev.driver->owner)) goto error; sd = spi_get_drvdata(spi); if (v4l2_device_register_subdev(v4l2_dev, sd)) sd = NULL; module_put(spi->dev.driver->owner); error: if (spi && sd == NULL) spi_unregister_device(spi); return sd; }
static int __init galileo_module_init(void) { struct spi_master *master; int err; pr_info("module init\n"); set_spi_quark_board_value(&spi_info, &spi_irq, &spi_master); err = -ENODEV; master = spi_busnum_to_master(spi_master); pr_info("master=%p\n", master); if (!master) goto out; dev = spi_new_device(master, &spi_info); pr_info("dev=%p\n", dev); if (!dev) goto out; if (spi_irq) { dev->irq = gpio_to_irq(spi_irq); irq_set_irq_type(dev->irq, IRQF_TRIGGER_RISING); } pr_info("802.15.4 chip registered\n"); err = 0; out: if (err) pr_err("Failed to register SPI device\n"); return err; }
static int hotplug_spi_init(void) { int bus_num; struct spi_master *slaves_spi_master; printk(KERN_ALERT "Adding SPI Device: %s, bus: %i, chip-sel: %i\n", slave_spi_board_info.modalias, slave_spi_board_info.bus_num, slave_spi_board_info.chip_select); /* Add the slave SPI device to the SPI bus * * These methods are used to hot-plug spi devices. * SPI devices are by nature NOT hot-pluggable, as * they cannot be probed for functionality etc. SPI * devices are normally cold-plugged during boot, that * is, they are added in the board description file: * /arch/arm/mach-omap2/board-devkit8000.c * Using this method we actually doing "hot" cold-plugging * adding devices using a kernel module. * Note that it is crusial that driver and device uses * the same name alias. If not, the device and driver * will not be paired and the probe method in the driver * not be called. */ bus_num = slave_spi_board_info.bus_num; slaves_spi_master = spi_busnum_to_master(bus_num); slave_spi_device = spi_new_device(slaves_spi_master, &slave_spi_board_info); if(slave_spi_device < 0) { printk(KERN_ALERT "Unsuccesful creating a new device\n"); return -1; } return 0; }
static int s3c2410_spigpio_probe(struct platform_device *dev) { struct spi_master *master; struct s3c2410_spigpio *sp; int ret; int i; master = spi_alloc_master(&dev->dev, sizeof(struct s3c2410_spigpio)); if (master == NULL) { dev_err(&dev->dev, "failed to allocate spi master\n"); ret = -ENOMEM; goto err; } sp = spi_master_get_devdata(master); platform_set_drvdata(dev, sp); /* copy in the plkatform data */ sp->info = dev->dev.platform_data; /* setup spi bitbang adaptor */ sp->bitbang.master = spi_master_get(master); sp->bitbang.chipselect = s3c2410_spigpio_chipselect; sp->bitbang.txrx_word[SPI_MODE_0] = s3c2410_spigpio_txrx_mode0; sp->bitbang.txrx_word[SPI_MODE_1] = s3c2410_spigpio_txrx_mode1; /* set state of spi pins */ s3c2410_gpio_setpin(sp->info->pin_clk, 0); s3c2410_gpio_setpin(sp->info->pin_mosi, 0); s3c2410_gpio_cfgpin(sp->info->pin_clk, S3C2410_GPIO_OUTPUT); s3c2410_gpio_cfgpin(sp->info->pin_mosi, S3C2410_GPIO_OUTPUT); s3c2410_gpio_cfgpin(sp->info->pin_miso, S3C2410_GPIO_INPUT); ret = spi_bitbang_start(&sp->bitbang); if (ret) goto err_no_bitbang; /* register the chips to go with the board */ for (i = 0; i < sp->info->board_size; i++) { dev_info(&dev->dev, "registering %p: %s\n", &sp->info->board_info[i], sp->info->board_info[i].modalias); sp->info->board_info[i].controller_data = sp; spi_new_device(master, sp->info->board_info + i); } return 0; err_no_bitbang: spi_master_put(sp->bitbang.master); err: return ret; }
static int __init as_spi_gpio_dev_probe(void) { struct platform_device *pdev; int err; struct spi_master *master; struct spi_device *slave; struct spi_board_info slave_info; pdev=platform_device_alloc("as_spi_gpio",DEVID); if(!pdev) { err=-ENOMEM; goto err; } err=platform_device_add(pdev); if(err) { printk(KERN_ERR PFX "platform_device_add failed with return code %d\n",err); platform_device_put(pdev); goto err; } memset(&slave_info,0,sizeof(slave_info)); strcpy(slave_info.modalias,"spidev"); slave_info.controller_data=(void*)SPI_GPIO_NO_CHIPSELECT; slave_info.max_speed_hz=MAX_FREQ; slave_info.chip_select=0; slave_info.mode=SPI_MODE; master=spi_busnum_to_master(DEVID); if(!master) { printk(KERN_ERR PFX "unable to get master for bus %d\n",DEVID); err=-EINVAL; goto err_unregister; } slave=spi_new_device(master,&slave_info); spi_master_put(master); if(!slave) { printk(KERN_ERR PFX "unable to create slave %d for bus %d\n",0,DEVID); /* Will most likely fail due to unsupported mode bits */ err=-EINVAL; goto err_unregister; } device=pdev; return 0; err_unregister: platform_device_unregister(pdev); err: as_spi_gpio_dev_cleanup(); return err; }
static int __init _spi_init(void) { int ret; unsigned char ch = 0x01; struct spi_master *master; struct spi_board_info spi_device_info = { .modalias = "ami-spi-device", .max_speed_hz = 12000000, //speed of your device splace can handle .bus_num = 0, //BUS number .chip_select = 0, .mode = 3, }; printk(KERN_INFO "spi basic driver init"); master = spi_busnum_to_master(spi_device_info.bus_num); if (!master) { printk(KERN_ALERT "Failed to create master device"); return -ENODEV; } //create a slave new device, given the master and device info sdev = spi_new_device(master, &spi_device_info); if (!sdev) { printk(KERN_ALERT "Failed to create slave device"); return -ENODEV; } sdev->bits_per_word = 8; ret = spi_setup(sdev); if (ret) { printk(KERN_ALERT "Failed to setup slave"); spi_unregister_device(sdev); return -ENODEV; } printk(KERN_ALERT "Writing ch=0x01 to spi interface"); spi_write(sdev, &ch, sizeof(ch)); return 0; } static void __exit _spi_exit(void) { printk(KERN_INFO "spi basic driver exit"); if (sdev) { unsigned char ch = 0xff; spi_write(sdev, &ch, sizeof(ch)); spi_unregister_device(sdev); } }
static int __devinit xilinx_spi_probe(struct platform_device *dev) { struct xspi_platform_data *pdata; struct resource *r; int irq, num_cs = 0, little_endian = 0, bits_per_word = 8; struct spi_master *master; u8 i; pdata = dev->dev.platform_data; if (pdata) { num_cs = pdata->num_chipselect; little_endian = pdata->little_endian; bits_per_word = pdata->bits_per_word; } #ifdef CONFIG_OF if (dev->dev.of_node) { const __be32 *prop; int len; /* number of slave select bits is required */ prop = of_get_property(dev->dev.of_node, "xlnx,num-ss-bits", &len); if (prop && len >= sizeof(*prop)) num_cs = __be32_to_cpup(prop); } #endif if (!num_cs) { dev_err(&dev->dev, "Missing slave select configuration data\n"); return -EINVAL; } r = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!r) return -ENODEV; irq = platform_get_irq(dev, 0); if (irq < 0) return -ENXIO; master = xilinx_spi_init(&dev->dev, r, irq, dev->id, num_cs, little_endian, bits_per_word); if (!master) return -ENODEV; if (pdata) { for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); } platform_set_drvdata(dev, master); return 0; }
static int __init mcp3901_hotplug(void) { int ret; struct spi_master *master; master = spi_busnum_to_master(SPI_BUS1); if(master == NULL) return -ENODEV; mcp3901_device = spi_new_device(master, &mcp3901_board_info); if(mcp3901_device == NULL) return -ENODEV; printk("Hotplugged MCP3901."); return 0; }
// ----------------------------------------------------------------------------------- static int __init init_maspi(void) { struct spi_master *master; printk(KERN_INFO "registering maspi spi device\n"); master = spi_busnum_to_master(0); if (!master) { printk(KERN_ALERT "could not find master spi driver"); return -1; } maspi_device = spi_new_device(master, &pseudo_spi_device); if (!maspi_device) { printk(KERN_ALERT "could not add extra spi device [CS2]"); return -1; } return 0; }
static __init int spisvc_init(void) { struct spi_master *m = NULL; struct spi_board_info board = { .modalias = "spidev", .max_speed_hz = 15058800, .mode = SPI_MODE_3, .platform_data = NULL, .bus_num = 0, .chip_select = 0, .irq = 0, }; if (SPI_INVALID_BUS == busnum) /* Bus not assigned: find SPI master with lowest bus number */ for (busnum = 0; SPI_MAX_BUS > busnum && NULL == m; busnum++) m = spi_busnum_to_master(busnum); else m = spi_busnum_to_master(busnum); if (!m) { pr_err("SPI bus not available.\n"); return -ENODEV; } board.bus_num = busnum = m->bus_num; board.chip_select = cs; spidev = spi_new_device(m, &board); if (!spidev) { dev_err(&m->dev, "Cannot add '%s' on bus %u, cs %u\n", board.modalias, board.bus_num, board.chip_select); return -ENODEV; } return 0; } module_init(spisvc_init); static __exit void spisvc_exit(void) { if (spidev) spi_unregister_device(spidev); } module_exit(spisvc_exit);
static inline __init int spi_int(void) { int ret; struct spi_board_info spi_device_info_1 = { .modalias = "spi_int", .max_speed_hz = speed_hz, .bus_num = spi_bus, .mode = 1, // depends on the mode we have to use this }; struct spi_master *master1; // for specifying I am using this driver for spi_master master1 = spi_busnum_to_master( spi_device_info_1.bus_num ); //assigning bus_number to master if( !master1 ) { printk( KERN_INFO"spi bus information for master not found"); return -ENODEV; // error to the kernel } spi_device_1 = spi_new_device( master1, &spi_device_info_1 ); // creation of spi device in kernel module if( !spi_device_1 ) { printk(KERN_INFO"spi device not able to create "); // this error is generated if we are using the same channel which bydefault spi is using return -ENODEV; } spi_device_1->bits_per_word = 32; // specifying the lenght of word that can spi transfer spi_device_1->cs_gpio =60; // for external GPIO as chip select ret = spi_setup( spi_pot_device); if( ret ) spi_unregister_device( spi_device_1 ); else printk( KERN_INFO "%d bus no andcs no %d", spi_bus, gpio_pin_chipselect ); return ret; } static inline void spi_release(void) { spi_unregister_device( spi_pot_device ); }
int qtft_spi_init(void) { int err=0; struct spi_master *master=NULL; struct spi_device *new_device=NULL; func_in(); err = spi_register_driver(&qtft_spi_dri_driver); if(err) { printk(KERN_ERR "Can't register spi driver \n"); goto out; } master = spi_busnum_to_master(SPI_BUS_NUM); if(!master) { printk(KERN_ERR "Can't get SPI bus %d\n",SPI_BUS_NUM); err = -ENODEV; goto err0; } new_device = spi_new_device(master, qtft_spi_dev_board_info); if(!new_device) { printk(KERN_ERR "Can't register spi device \n"); err = -ENODEV; goto err0; } goto out; err0: spi_unregister_driver(&qtft_spi_dri_driver); out: func_out(); return err; }
struct v4l2_subdev *v4l2_spi_new_subdev(struct v4l2_device *v4l2_dev, struct spi_master *master, struct spi_board_info *info) { struct v4l2_subdev *sd = NULL; struct spi_device *spi = NULL; BUG_ON(!v4l2_dev); if (info->modalias) request_module(info->modalias); spi = spi_new_device(master, info); if (spi == NULL || spi->dev.driver == NULL) goto error; if (!try_module_get(spi->dev.driver->owner)) goto error; sd = spi_get_drvdata(spi); /* Register with the v4l2_device which increases the module's use count as well. */ if (v4l2_device_register_subdev(v4l2_dev, sd)) sd = NULL; /* Decrease the module use count to match the first try_module_get. */ module_put(spi->dev.driver->owner); error: /* If we have a client but no subdev, then something went wrong and we must unregister the client. */ if (spi && sd == NULL) spi_unregister_device(spi); return sd; }
static inline __init int spi_init(void) { struct spi_board_info spi_pot_device_info = { .modalias = "itrigue", .max_speed_hz = speed_hz, .bus_num = pot_spi_bus, .chip_select = pot_spi_cs, .mode = 0, }; struct spi_master *master; int ret; master = spi_busnum_to_master( spi_pot_device_info.bus_num ); if( !master ) return -ENODEV; spi_pot_device = spi_new_device( master, &spi_pot_device_info ); if( !spi_pot_device ) return -ENODEV; spi_pot_device->bits_per_word = 16; ret = spi_setup( spi_pot_device ); if( ret ) spi_unregister_device( spi_pot_device ); else printk( KERN_INFO "I-Trigue 3300 potentiometers registered to SPI bus %u, chipselect %u\n", pot_spi_bus, pot_spi_cs ); return ret; } static inline void spi_exit(void) { spi_unregister_device( spi_pot_device ); }
static int bcm53xxspi_bcma_probe(struct bcma_device *core) { struct bcm53xxspi *b53spi; struct spi_master *master; int err; if (core->bus->drv_cc.core->id.rev != 42) { pr_err("SPI on SoC with unsupported ChipCommon rev\n"); return -ENOTSUPP; } master = spi_alloc_master(&core->dev, sizeof(*b53spi)); if (!master) return -ENOMEM; b53spi = spi_master_get_devdata(master); b53spi->master = master; b53spi->core = core; master->transfer_one = bcm53xxspi_transfer_one; bcma_set_drvdata(core, b53spi); err = devm_spi_register_master(&core->dev, master); if (err) { spi_master_put(master); bcma_set_drvdata(core, NULL); goto out; } /* Broadcom SoCs (at least with the CC rev 42) use SPI for flash only */ spi_new_device(master, &bcm53xx_info); out: return err; }
static void spi_lm70llp_attach(struct parport *p) { struct pardevice *pd; struct spi_lm70llp *pp; struct spi_master *master; int status; if (lm70llp) { printk(KERN_WARNING "%s: spi_lm70llp instance already loaded. Aborting.\n", DRVNAME); return; } /* TODO: this just _assumes_ a lm70 is there ... no probe; * the lm70 driver could verify it, reading the manf ID. */ master = spi_alloc_master(p->physport->dev, sizeof *pp); if (!master) { status = -ENOMEM; goto out_fail; } pp = spi_master_get_devdata(master); master->bus_num = -1; /* dynamic alloc of a bus number */ master->num_chipselect = 1; /* * SPI and bitbang hookup. */ pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = lm70_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx; pp->bitbang.flags = SPI_3WIRE; /* * Parport hookup */ pp->port = p; pd = parport_register_device(p, DRVNAME, NULL, NULL, NULL, PARPORT_FLAG_EXCL, pp); if (!pd) { status = -ENOMEM; goto out_free_master; } pp->pd = pd; status = parport_claim(pd); if (status < 0) goto out_parport_unreg; /* * Start SPI ... */ status = spi_bitbang_start(&pp->bitbang); if (status < 0) { printk(KERN_WARNING "%s: spi_bitbang_start failed with status %d\n", DRVNAME, status); goto out_off_and_release; } /* * The modalias name MUST match the device_driver name * for the bus glue code to match and subsequently bind them. * We are binding to the generic drivers/hwmon/lm70.c device * driver. */ strcpy(pp->info.modalias, "lm70"); pp->info.max_speed_hz = 6 * 1000 * 1000; pp->info.chip_select = 0; pp->info.mode = SPI_3WIRE | SPI_MODE_0; /* power up the chip, and let the LM70 control SI/SO */ parport_write_data(pp->port, lm70_INIT); /* Enable access to our primary data structure via * the board info's (void *)controller_data. */ pp->info.controller_data = pp; pp->spidev_lm70 = spi_new_device(pp->bitbang.master, &pp->info); if (pp->spidev_lm70) dev_dbg(&pp->spidev_lm70->dev, "spidev_lm70 at %s\n", dev_name(&pp->spidev_lm70->dev)); else { printk(KERN_WARNING "%s: spi_new_device failed\n", DRVNAME); status = -ENODEV; goto out_bitbang_stop; } pp->spidev_lm70->bits_per_word = 8; lm70llp = pp; return; out_bitbang_stop: spi_bitbang_stop(&pp->bitbang); out_off_and_release: /* power down */ parport_write_data(pp->port, 0); mdelay(10); parport_release(pp->pd); out_parport_unreg: parport_unregister_device(pd); out_free_master: (void) spi_master_put(master); out_fail: pr_info("%s: spi_lm70llp probe fail, status %d\n", DRVNAME, status); }
static void butterfly_attach(struct parport *p) { struct pardevice *pd; int status; struct butterfly *pp; struct spi_master *master; struct device *dev = p->physport->dev; if (butterfly || !dev) return; /* REVISIT: this just _assumes_ a butterfly is there ... no probe, * and no way to be selective about what it binds to. */ master = spi_alloc_master(dev, sizeof *pp); if (!master) { status = -ENOMEM; goto done; } pp = spi_master_get_devdata(master); /* * SPI and bitbang hookup * * use default setup(), cleanup(), and transfer() methods; and * only bother implementing mode 0. Start it later. */ master->bus_num = 42; master->num_chipselect = 2; pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = butterfly_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0; /* * parport hookup */ pp->port = p; pd = parport_register_device(p, "spi_butterfly", NULL, NULL, NULL, 0 /* FLAGS */, pp); if (!pd) { status = -ENOMEM; goto clean0; } pp->pd = pd; status = parport_claim(pd); if (status < 0) goto clean1; /* * Butterfly reset, powerup, run firmware */ pr_debug("%s: powerup/reset Butterfly\n", p->name); /* nCS for dataflash (this bit is inverted on output) */ parport_frob_control(pp->port, spi_cs_bit, 0); /* stabilize power with chip in reset (nRESET), and * spi_sck_bit clear (CPOL=0) */ pp->lastbyte |= vcc_bits; parport_write_data(pp->port, pp->lastbyte); msleep(5); /* take it out of reset; assume long reset delay */ pp->lastbyte |= butterfly_nreset; parport_write_data(pp->port, pp->lastbyte); msleep(100); /* * Start SPI ... for now, hide that we're two physical busses. */ status = spi_bitbang_start(&pp->bitbang); if (status < 0) goto clean2; /* Bus 1 lets us talk to at45db041b (firmware disables AVR SPI), AVR * (firmware resets at45, acts as spi slave) or neither (we ignore * both, AVR uses AT45). Here we expect firmware for the first option. */ pp->info[0].max_speed_hz = 15 * 1000 * 1000; strcpy(pp->info[0].modalias, "mtd_dataflash"); pp->info[0].platform_data = &flash; pp->info[0].chip_select = 1; pp->info[0].controller_data = pp; pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]); if (pp->dataflash) pr_debug("%s: dataflash at %s\n", p->name, dev_name(&pp->dataflash->dev)); // dev_info(_what?_, ...) pr_info("%s: AVR Butterfly\n", p->name); butterfly = pp; return; clean2: /* turn off VCC */ parport_write_data(pp->port, 0); parport_release(pp->pd); clean1: parport_unregister_device(pd); clean0: (void) spi_master_put(pp->bitbang.master); done: pr_debug("%s: butterfly probe, fail %d\n", p->name, status); }
/* * s3c6410_spi_probe - probe spi driver * @pdev : platform device struct * * platform driver member function for probing */ static int s3c6410_spi_probe(struct platform_device *pdev) { struct s3c6410_spi *hw; struct spi_master *master; struct spi_board_info *bi; struct resource *res; int err = 0; int i; unsigned int spi_chcfg; master = spi_alloc_master(&pdev->dev, sizeof(struct s3c6410_spi)); if (master == NULL) { dev_err(&pdev->dev, "No memory for spi_master\n"); err = -ENOMEM; goto err_nomem; } hw = spi_master_get_devdata(master); memset(hw, 0, sizeof(struct s3c6410_spi)); hw->master = spi_master_get(master); hw->master->num_chipselect = 2; hw->pdata = pdev->dev.platform_data; hw->dev = &pdev->dev; hw->id = pdev->id; hw->bits_per_word = 16; if (hw->pdata == NULL) { dev_err(&pdev->dev, "No platform data supplied\n"); err = -ENOENT; goto err_no_pdata; } platform_set_drvdata(pdev, hw); /* setup the state for the bitbang driver */ hw->bitbang.master = hw->master; hw->bitbang.setup_transfer = s3c6410_spi_setupxfer; hw->bitbang.chipselect = s3c6410_spi_chipsel; hw->bitbang.txrx_bufs = s3c6410_spi_txrx; hw->bitbang.master->setup = s3c6410_spi_setup; init_completion(&hw->done); /* find and map our resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); err = -ENOENT; goto err_no_iores; } hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1, pdev->name); if (hw->ioarea == NULL) { dev_err(&pdev->dev, "Cannot reserve region\n"); err = -ENXIO; goto err_no_iores; } hw->regs = ioremap(res->start, (res->end - res->start)+1); hw->regs += 0x1000 * hw->id; if (hw->regs == NULL) { dev_err(&pdev->dev, "Cannot map IO\n"); err = -ENXIO; goto err_no_iomap; } hw->irq = platform_get_irq(pdev, 0); if (hw->irq < 0) { dev_err(&pdev->dev, "No IRQ specified\n"); err = -ENOENT; goto err_no_irq; } err = request_irq(hw->irq, s3c6410_spi_irq, IRQF_DISABLED, pdev->name, hw); if (err) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); goto err_no_irq; } hw->clk = clk_get(&pdev->dev, "spi"); if (IS_ERR(hw->clk)) { dev_err(&pdev->dev, "No clock for device\n"); err = PTR_ERR(hw->clk); goto err_no_clk; } printk("S3C6410 SPI Driver at 0x%x, irq %d\n", (unsigned int)hw->regs, hw->irq); /* for the moment, permanently enable the clock */ #ifdef CONFIG_SPICLK_PCLK clk_enable(hw->clk); hw->in_clk = clk_get_rate(hw->clk); #elif defined (CONFIG_SPICLK_EPLL) writel((readl(S3C_PCLK_GATE)|S3C_CLKCON_PCLK_SPI0|S3C_CLKCON_PCLK_SPI1),S3C_PCLK_GATE); writel((readl(S3C_SCLK_GATE)|S3C_CLKCON_SCLK_SPI0|S3C_CLKCON_SCLK_SPI1),S3C_SCLK_GATE); writel(readl(S3C_CLK_SRC)|S3C_CLKSRC_MPLL_CLKSEL, S3C_CLK_SRC); /* Set SPi Clock to DOUTMPLL*/ if(hw->id == 0) /* SPI_CHANNEL = 0 */ writel((readl(S3C_CLK_SRC)&~(0x3<<14))|(1<<14), S3C_CLK_SRC); else /* SPI_CHANNEL = 1 */ writel((readl(S3C_CLK_SRC)&~(0x3<<16))|(1<<16), S3C_CLK_SRC); /* CLK_DIV2 setting */ /* SPI Input Clock(88.87Mhz) = 266.66Mhz / (2 + 1)*/ writel(((readl(S3C_CLK_DIV2) & ~(0xff << 0)) | 2) , S3C_CLK_DIV2); hw->in_clk = 266660000; #elif defined (CONFIG_SPICLK_USBCLK) writel((readl(S3C_PCLK_GATE)| S3C_CLKCON_PCLK_SPI0|S3C_CLKCON_PCLK_SPI1),S3C_PCLK_GATE); writel((readl(S3C_SCLK_GATE)|S3C_CLKCON_SCLK_SPI0_48|S3C_CLKCON_SCLK_SPI1_48),S3C_SCLK_GATE); hw->in_clk = 48000000; #endif printk("SPI: Source Clock = %ldMhz\n", hw->in_clk); /* initialize the gpio */ if (hw->id == 0) { s3c_gpio_cfgpin(S3C64XX_GPC(0), S3C64XX_GPC0_SPI_MISO0); s3c_gpio_cfgpin(S3C64XX_GPC(1), S3C64XX_GPC1_SPI_CLK0); s3c_gpio_cfgpin(S3C64XX_GPC(2), S3C64XX_GPC2_SPI_MOSI0); s3c_gpio_cfgpin(S3C64XX_GPC(3), S3C64XX_GPC3_SPI_nCS0); s3c_gpio_setpull(S3C64XX_GPC(0), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPC(1), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPC(2), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPC(3), S3C_GPIO_PULL_UP); } else { s3c_gpio_cfgpin(S3C64XX_GPC(4), S3C64XX_GPC4_SPI_MISO1); s3c_gpio_cfgpin(S3C64XX_GPC(5), S3C64XX_GPC5_SPI_CLK1); s3c_gpio_cfgpin(S3C64XX_GPC(6), S3C64XX_GPC6_SPI_MOSI1); s3c_gpio_cfgpin(S3C64XX_GPC(7), S3C64XX_GPC7_SPI_nCS1); s3c_gpio_setpull(S3C64XX_GPC(4), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPC(5), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPC(6), S3C_GPIO_PULL_UP); s3c_gpio_setpull(S3C64XX_GPC(7), S3C_GPIO_PULL_UP); } /* SW Reset */ writel(readl(hw->regs + S3C_CH_CFG) | SPI_CH_SW_RST, hw->regs + S3C_CH_CFG); udelay(100); writel(readl(hw->regs + S3C_CH_CFG) & (~SPI_CH_SW_RST), hw->regs + S3C_CH_CFG); udelay(100); /* disable SPI Interrupt */ writel(SPI_INT_ALL_DISABLE, hw->regs + S3C_SPI_INT_EN); /* Set transfer type (CPOL & CPHA set) */ spi_chcfg = readl(hw->regs + S3C_CH_CFG); spi_chcfg &= ~SPI_CH_HSPD_EN; spi_chcfg |= SPI_CH_FORMAT_B | SPI_CH_RISING | SPI_CH_MASTER; writel(spi_chcfg, hw->regs + S3C_CH_CFG); /* Set NSSOUT to start high after Reset */ s3c6410_spi_set_cs(hw, BITBANG_CS_INACTIVE); /* register our spi controller */ err = spi_bitbang_start(&hw->bitbang); if (err) { dev_err(&pdev->dev, "Failed to register SPI master\n"); goto err_register; } /* register all the devices associated */ bi = hw->pdata->board_info; for (i = 0; i < hw->pdata->board_size; i++, bi++) { dev_info(hw->dev, "registering %s\n", bi->modalias); bi->controller_data = hw; spi_new_device(master, bi); } /* for suspend & resume */ test_hw = hw; return 0; err_register: clk_disable(hw->clk); clk_put(hw->clk); err_no_clk: free_irq(hw->irq, hw); err_no_irq: iounmap(hw->regs); err_no_iomap: release_resource(hw->ioarea); kfree(hw->ioarea); err_no_iores: err_no_pdata: spi_master_put(hw->master);; err_nomem: return err; }
static int __init fbtft_device_init(void) { struct spi_master *master = NULL; struct spi_board_info *display = NULL; const struct fbtft_platform_data *pdata = NULL; const struct fbtft_gpio *gpio = NULL; char *p_name, *p_num; bool found = false; int i; long val; int ret = 0; pr_debug("\n\n"DRVNAME": init\n"); /* parse module parameter: gpios */ if (gpios_num > MAX_GPIOS) { pr_err(DRVNAME": gpios parameter: exceeded max array size: %d\n", MAX_GPIOS); return -EINVAL; } if (gpios_num > 0) { for (i=0;i<gpios_num;i++) { if (strchr(gpios[i], ':') == NULL) { pr_err(DRVNAME": error missing ':' in gpios parameter: %s\n", gpios[i]); return -EINVAL; } p_num = gpios[i]; p_name = strsep(&p_num, ":"); if (p_name == NULL || p_num == NULL) { pr_err(DRVNAME": something bad happenned parsing gpios parameter: %s\n", gpios[i]); return -EINVAL; } ret = kstrtol(p_num, 10, &val); if (ret) { pr_err(DRVNAME": could not parse number in gpios parameter: %s:%s\n", p_name, p_num); return -EINVAL; } strcpy(fbtft_device_param_gpios[i].name, p_name); fbtft_device_param_gpios[i].gpio = (int) val; pdata = &fbtft_device_param_pdata; } } if (verbose > 2) pr_spi_devices(); /* print list of registered SPI devices */ if (verbose > 2) pr_p_devices(); /* print list of 'fb' platform devices */ if (name == NULL) { pr_err(DRVNAME": missing module parameter: 'name'\n"); pr_err(DRVNAME": Use 'modinfo -p "DRVNAME"' to get all parameters\n"); return -EINVAL; } pr_debug(DRVNAME": name='%s', busnum=%d, cs=%d\n", name, busnum, cs); if (rotate > 3) { pr_warning("argument 'rotate' illegal value: %d (0-3). Setting it to 0.\n", rotate); rotate = 0; } /* name=list lists all supported drivers */ if (strncmp(name, "list", 32) == 0) { pr_info(DRVNAME": Supported drivers:\n"); for (i=0; i < ARRAY_SIZE(fbtft_device_spi_displays); i++) { pr_info(DRVNAME": %s\n", fbtft_device_spi_displays[i].modalias); } for (i=0; i < ARRAY_SIZE(fbtft_device_pdev_displays); i++) { pr_info(DRVNAME": %s\n", fbtft_device_pdev_displays[i].name); } return -ECANCELED; } /* see if it is a SPI device */ for (i=0; i < ARRAY_SIZE(fbtft_device_spi_displays); i++) { if (strncmp(name, fbtft_device_spi_displays[i].modalias, 32) == 0) { master = spi_busnum_to_master(busnum); if (!master) { pr_err(DRVNAME": spi_busnum_to_master(%d) returned NULL\n", busnum); return -EINVAL; } fbtft_device_delete(master, cs); /* make sure it's available */ display = &fbtft_device_spi_displays[i]; display->chip_select = cs; display->bus_num = busnum; if (speed) display->max_speed_hz = speed; if (mode != -1) display->mode = mode; if (pdata) display->platform_data = pdata; pdata = display->platform_data; ((struct fbtft_platform_data *)pdata)->rotate = rotate; ((struct fbtft_platform_data *)pdata)->bgr = bgr; if (fps) ((struct fbtft_platform_data *)pdata)->fps = fps; if (txbuflen) ((struct fbtft_platform_data *)pdata)->txbuflen = txbuflen; spi_device = spi_new_device(master, display); put_device(&master->dev); if (!spi_device) { pr_err(DRVNAME": spi_new_device() returned NULL\n"); return -EPERM; } found = true; break; } } if (!found) { /* see if it is a platform_device */ for (i=0; i < ARRAY_SIZE(fbtft_device_pdev_displays); i++) { if (strncmp(name, fbtft_device_pdev_displays[i].name, 32) == 0) { p_device = &fbtft_device_pdev_displays[i]; ret = platform_device_register(p_device); if (ret < 0) { pr_err(DRVNAME": platform_device_register() returned %d\n", ret); return ret; } if (pdata) p_device->dev.platform_data = (void *)pdata; pdata = p_device->dev.platform_data; ((struct fbtft_platform_data *)pdata)->rotate = rotate; ((struct fbtft_platform_data *)pdata)->bgr = bgr; if (fps) ((struct fbtft_platform_data *)pdata)->fps = fps; if (txbuflen) ((struct fbtft_platform_data *)pdata)->txbuflen = txbuflen; found = true; break; } } } if (!found) { pr_err(DRVNAME": device not supported: '%s'\n", name); return -EINVAL; } if (verbose) pr_info(DRVNAME": GPIOS used by '%s':\n", name); gpio = pdata->gpios; if (!gpio) { pr_err(DRVNAME": gpio is unexspectedly empty\n"); return -EINVAL; } while (verbose && gpio->name[0]) { pr_info(DRVNAME": '%s' = GPIO%d\n", gpio->name, gpio->gpio); gpio++; } if (spi_device && (verbose > 1)) pr_spi_devices(); if (p_device && (verbose > 1)) pr_p_devices(); return 0; }
int __init bcm_mpi_init(bcm_mpi_t *t, const bcm_mpi_params_t *params) { int ret = -1; #ifdef BCMPH_USE_SPI_DRIVER # ifndef BCMPH_NOHW struct spi_master *master; struct spi_board_info board_info; # endif // !BCMPH_NOHW #endif // BCMPH_USE_SPI_DRIVER bcm_pr_debug("%s()\n", __func__); bcm_assert(NULL != params); #ifndef BCMPH_NOHW t->trx_opts.fill_byte = params->fill_byte; t->trx_opts.wait_completion_with_irq = params->wait_completion_with_irq; t->trx_opts.drop_cs_after_each_byte = params->drop_cs_after_each_byte; t->trx_opts.cs_off_clk_cycles = params->cs_off_clk_cycles; #endif // !BCMPH_NOHW #ifdef BCMPH_USE_SPI_DRIVER t->mpi_clk = params->clk; # ifndef BCMPH_NOHW master = spi_busnum_to_master(params->bus_num); if (NULL == master) { bcm_pr_err("No SPI master found for bus num %d. Module bcm63xx-spi not loaded ?\n", (int)(params->bus_num)); ret = -EINVAL; goto fail_master; } memset(&(board_info), 0, sizeof(board_info)); strcpy(board_info.modalias, driver_name); board_info.max_speed_hz = params->clk; board_info.bus_num = params->bus_num; board_info.chip_select = params->cs; board_info.mode = SPI_MODE_3; t->dev = spi_new_device(master, &(board_info)); if (NULL == t->dev) { bcm_pr_err("Failed to add SPI device (busnum = %d, chip select = %d, clock = %lu)\n", (int)(params->bus_num), (int)(params->cs), (unsigned long)(params->clk)); ret = -ENOMEM; goto fail_new_dev; } put_device(&(master->dev)); /* Lock the bus */ if ((params->has_exclusive_bus_access) && (!bcm_drv_param_mpi_no_exclusive_bus_access)) { spi_bus_lock(t->dev->master); t->bus_is_locked = true; } bcm_mpi_enable_extra_CSs(params->cs); # ifdef BCMPH_DEBUG_MPI t->trace_len = 0; # endif // BCMPH_DEBUG_MPI return (0); spi_unregister_device(t->dev); fail_new_dev: put_device(&(master->dev)); fail_master: # else // BCMPH_NOHW ret = 0; # endif // BCMPH_NOHW #else // !BCMPH_USE_SPI_DRIVER # ifndef BCMPH_NOHW t->mpi_cs = params->cs; t->clk_cfg = bcm_mpi_get_clk_cfg(params->clk, params->cs_off_clk_cycles); bcm_mpi_enable_extra_CSs(params->cs); if (bcm_mpi_dev_data.ref_count <= 0) { struct device_driver *spi_driver = driver_find(bcm63xx_spi_driver.driver.name, &platform_bus_type); if (NULL != spi_driver) { bcm_pr_err("Error: Driver '%s' is already registered, aborting...\n", bcm63xx_spi_driver.driver.name); ret = -EBUSY; } else { ret = platform_driver_register(&(bcm63xx_spi_driver)); } bcm_assert(((ret) && (0 == bcm_mpi_dev_data.ref_count)) || ((!ret) && (1 == bcm_mpi_dev_data.ref_count))); } else { bcm_mpi_dev_data.ref_count += 1; ret = 0; } if (!ret) { bcm_assert(bcm_mpi_dev_data.ref_count > 0); if (params->cs > bcm_mpi_dev_data.num_chipselect) { dev_err(&(bcm_mpi_dev_data.pdev->dev), "%s, unsupported slave %d\n", __func__, params->cs); if (1 == bcm_mpi_dev_data.ref_count) { platform_driver_unregister(&(bcm63xx_spi_driver)); } bcm_mpi_dev_data.ref_count -= 1; ret = -EINVAL; } else { t->dev_data = &(bcm_mpi_dev_data); } } # else // BCMPH_NOHW ret = 0; # endif // BCMPH_NOHW #endif // !BCMPH_USE_SPI_DRIVER return (ret); }
static void butterfly_attach(struct parport *p) { struct pardevice *pd; int status; struct butterfly *pp; struct spi_master *master; struct platform_device *pdev; if (butterfly) return; /* REVISIT: this just _assumes_ a butterfly is there ... no probe, * and no way to be selective about what it binds to. */ /* FIXME where should master->cdev.dev come from? * e.g. /sys/bus/pnp0/00:0b, some PCI thing, etc * setting up a platform device like this is an ugly kluge... */ pdev = platform_device_register_simple("butterfly", -1, NULL, 0); master = spi_alloc_master(&pdev->dev, sizeof *pp); if (!master) { status = -ENOMEM; goto done; } pp = spi_master_get_devdata(master); /* * SPI and bitbang hookup * * use default setup(), cleanup(), and transfer() methods; and * only bother implementing mode 0. Start it later. */ master->bus_num = 42; master->num_chipselect = 2; pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = butterfly_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0; /* * parport hookup */ pp->port = p; pd = parport_register_device(p, "spi_butterfly", NULL, NULL, NULL, 0 /* FLAGS */, pp); if (!pd) { status = -ENOMEM; goto clean0; } pp->pd = pd; status = parport_claim(pd); if (status < 0) goto clean1; /* * Butterfly reset, powerup, run firmware */ pr_debug("%s: powerup/reset Butterfly\n", p->name); /* nCS for dataflash (this bit is inverted on output) */ parport_frob_control(pp->port, spi_cs_bit, 0); /* stabilize power with chip in reset (nRESET), and * both spi_sck_bit and usi_sck_bit clear (CPOL=0) */ pp->lastbyte |= vcc_bits; parport_write_data(pp->port, pp->lastbyte); msleep(5); /* take it out of reset; assume long reset delay */ pp->lastbyte |= butterfly_nreset; parport_write_data(pp->port, pp->lastbyte); msleep(100); /* * Start SPI ... for now, hide that we're two physical busses. */ status = spi_bitbang_start(&pp->bitbang); if (status < 0) goto clean2; /* Bus 1 lets us talk to at45db041b (firmware disables AVR) * or AVR (firmware resets at45, acts as spi slave) */ pp->info[0].max_speed_hz = 15 * 1000 * 1000; strcpy(pp->info[0].modalias, "mtd_dataflash"); pp->info[0].platform_data = &flash; pp->info[0].chip_select = 1; pp->info[0].controller_data = pp; pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]); if (pp->dataflash) pr_debug("%s: dataflash at %s\n", p->name, pp->dataflash->dev.bus_id); #ifdef HAVE_USI /* even more custom AVR firmware */ pp->info[1].max_speed_hz = 10 /* ?? */ * 1000 * 1000; strcpy(pp->info[1].modalias, "butterfly"); // pp->info[1].platform_data = ... TBD ... ; pp->info[1].chip_select = 2, pp->info[1].controller_data = pp; pp->butterfly = spi_new_device(pp->bitbang.master, &pp->info[1]); if (pp->butterfly) pr_debug("%s: butterfly at %s\n", p->name, pp->butterfly->dev.bus_id); /* FIXME setup ACK for the IRQ line ... */ #endif // dev_info(_what?_, ...) pr_info("%s: AVR Butterfly\n", p->name); butterfly = pp; return; clean2: /* turn off VCC */ parport_write_data(pp->port, 0); parport_release(pp->pd); clean1: parport_unregister_device(pd); clean0: (void) spi_master_put(pp->bitbang.master); done: platform_device_unregister(pdev); pr_debug("%s: butterfly probe, fail %d\n", p->name, status); }
static int spi_gpio_probe(struct platform_device *pdev) { struct spi_master *master; struct spi_gpio_platform_data *pdata; struct spi_gpio *sp; struct spi_device *spidev; int err; pdata = pdev->dev.platform_data; if (!pdata) return -ENXIO; err = -ENOMEM; master = spi_alloc_master(&pdev->dev, sizeof(struct spi_gpio)); if (!master) goto err_alloc_master; sp = spi_master_get_devdata(master); platform_set_drvdata(pdev, sp); sp->info = pdata; err = gpio_request(pdata->pin_clk, "spi_clock"); if (err) goto err_request_clk; err = gpio_request(pdata->pin_mosi, "spi_mosi"); if (err) goto err_request_mosi; err = gpio_request(pdata->pin_miso, "spi_miso"); if (err) goto err_request_miso; err = gpio_request(pdata->pin_cs, "spi_cs"); if (err) goto err_request_cs; sp->bitbang.master = spi_master_get(master); sp->bitbang.master->bus_num = -1; sp->bitbang.master->num_chipselect = 1; sp->bitbang.chipselect = spi_gpio_chipselect; sp->bitbang.txrx_word[SPI_MODE_0] = spi_gpio_txrx_mode0; sp->bitbang.txrx_word[SPI_MODE_1] = spi_gpio_txrx_mode1; sp->bitbang.txrx_word[SPI_MODE_2] = spi_gpio_txrx_mode2; sp->bitbang.txrx_word[SPI_MODE_3] = spi_gpio_txrx_mode3; gpio_direction_output(pdata->pin_clk, 0); gpio_direction_output(pdata->pin_mosi, 0); gpio_direction_output(pdata->pin_cs, pdata->cs_activelow ? 1 : 0); gpio_direction_input(pdata->pin_miso); err = spi_bitbang_start(&sp->bitbang); if (err) goto err_no_bitbang; err = pdata->boardinfo_setup(&sp->bi, master, pdata->boardinfo_setup_data); if (err) goto err_bi_setup; sp->bi.controller_data = sp; spidev = spi_new_device(master, &sp->bi); if (!spidev) goto err_new_dev; return 0; err_new_dev: err_bi_setup: spi_bitbang_stop(&sp->bitbang); err_no_bitbang: spi_master_put(sp->bitbang.master); gpio_free(pdata->pin_cs); err_request_cs: gpio_free(pdata->pin_miso); err_request_miso: gpio_free(pdata->pin_mosi); err_request_mosi: gpio_free(pdata->pin_clk); err_request_clk: kfree(master); err_alloc_master: return err; }
static int s3c24xx_spi_probe(struct platform_device *pdev) { struct s3c24xx_spi *hw; struct spi_master *master; struct spi_board_info *bi; struct resource *res; int err = 0; int i; master = spi_alloc_master(&pdev->dev, sizeof(struct s3c24xx_spi)); if (master == NULL) { dev_err(&pdev->dev, "No memory for spi_master\n"); err = -ENOMEM; goto err_nomem; } hw = spi_master_get_devdata(master); memset(hw, 0, sizeof(struct s3c24xx_spi)); hw->master = spi_master_get(master); hw->pdata = pdev->dev.platform_data; hw->dev = &pdev->dev; if (hw->pdata == NULL) { dev_err(&pdev->dev, "No platform data supplied\n"); err = -ENOENT; goto err_no_pdata; } platform_set_drvdata(pdev, hw); init_completion(&hw->done); /* setup the state for the bitbang driver */ hw->bitbang.master = hw->master; hw->bitbang.setup_transfer = s3c24xx_spi_setupxfer; hw->bitbang.chipselect = s3c24xx_spi_chipsel; hw->bitbang.txrx_bufs = s3c24xx_spi_txrx; hw->bitbang.master->setup = s3c24xx_spi_setup; dev_dbg(hw->dev, "bitbang at %p\n", &hw->bitbang); /* find and map our resources */ res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (res == NULL) { dev_err(&pdev->dev, "Cannot get IORESOURCE_MEM\n"); err = -ENOENT; goto err_no_iores; } hw->ioarea = request_mem_region(res->start, (res->end - res->start)+1, pdev->name); if (hw->ioarea == NULL) { dev_err(&pdev->dev, "Cannot reserve region\n"); err = -ENXIO; goto err_no_iores; } hw->regs = ioremap(res->start, (res->end - res->start)+1); if (hw->regs == NULL) { dev_err(&pdev->dev, "Cannot map IO\n"); err = -ENXIO; goto err_no_iomap; } hw->irq = platform_get_irq(pdev, 0); if (hw->irq < 0) { dev_err(&pdev->dev, "No IRQ specified\n"); err = -ENOENT; goto err_no_irq; } err = request_irq(hw->irq, s3c24xx_spi_irq, 0, pdev->name, hw); if (err) { dev_err(&pdev->dev, "Cannot claim IRQ\n"); goto err_no_irq; } hw->clk = clk_get(&pdev->dev, "spi"); if (IS_ERR(hw->clk)) { dev_err(&pdev->dev, "No clock for device\n"); err = PTR_ERR(hw->clk); goto err_no_clk; } /* for the moment, permanently enable the clock */ clk_enable(hw->clk); /* program defaults into the registers */ writeb(0xff, hw->regs + S3C2410_SPPRE); writeb(SPPIN_DEFAULT, hw->regs + S3C2410_SPPIN); writeb(SPCON_DEFAULT, hw->regs + S3C2410_SPCON); /* setup any gpio we can */ if (!hw->pdata->set_cs) { hw->set_cs = s3c24xx_spi_gpiocs; s3c2410_gpio_setpin(hw->pdata->pin_cs, 1); s3c2410_gpio_cfgpin(hw->pdata->pin_cs, S3C2410_GPIO_OUTPUT); } else hw->set_cs = hw->pdata->set_cs; /* register our spi controller */ err = spi_bitbang_start(&hw->bitbang); if (err) { dev_err(&pdev->dev, "Failed to register SPI master\n"); goto err_register; } dev_dbg(hw->dev, "shutdown=%d\n", hw->bitbang.shutdown); /* register all the devices associated */ bi = &hw->pdata->board_info[0]; for (i = 0; i < hw->pdata->board_size; i++, bi++) { dev_info(hw->dev, "registering %s\n", bi->modalias); bi->controller_data = hw; spi_new_device(master, bi); } return 0; err_register: clk_disable(hw->clk); clk_put(hw->clk); err_no_clk: free_irq(hw->irq, hw); err_no_irq: iounmap(hw->regs); err_no_iomap: release_resource(hw->ioarea); kfree(hw->ioarea); err_no_iores: err_no_pdata: spi_master_put(hw->master);; err_nomem: return err; }
/****************************** register spi device and attach it to Master driver ******************************/ static int reg_spi_device(void) { int retval = 0; struct spi_board_info spi_device_info = { .modalias = "nrf24l01+", .max_speed_hz = 5000000, .bus_num = 0, .chip_select = 1, .mode = 0, }; struct spi_master *master; master = spi_busnum_to_master(spi_device_info.bus_num); if(!master){ printk(KERN_ALERT "getting master device is failed!!\n"); retval = -ENODEV; goto out; } spi_device = spi_new_device(master,&spi_device_info); if(!spi_device){ printk(KERN_ALERT "registering spi device is failed!!\n"); retval = -ENODEV; goto out; } spi_device->bits_per_word = 8; retval = spi_setup(spi_device); if(retval){ spi_unregister_device(spi_device); goto out; } return 0; out: return retval; } /****************************** Module initialization function ******************************/ static int __init nrf_init(void) { int retval = 0; printk(KERN_INFO "hello from module!!\n"); retval = reg_dev(); if(retval != 0) goto out; retval = reg_spi_device(); if(retval != 0) goto out; radio_init(); return 0; out: return retval; }
static int xilinx_spi_probe(struct platform_device *pdev) { struct xilinx_spi *xspi; struct xspi_platform_data *pdata; struct resource *res; int ret, num_cs = 0, bits_per_word = 8; struct spi_master *master; u32 tmp; u8 i; pdata = dev_get_platdata(&pdev->dev); if (pdata) { num_cs = pdata->num_chipselect; bits_per_word = pdata->bits_per_word; } else { of_property_read_u32(pdev->dev.of_node, "xlnx,num-ss-bits", &num_cs); } if (!num_cs) { dev_err(&pdev->dev, "Missing slave select configuration data\n"); return -EINVAL; } if (num_cs > XILINX_SPI_MAX_CS) { dev_err(&pdev->dev, "Invalid number of spi slaves\n"); return -EINVAL; } master = spi_alloc_master(&pdev->dev, sizeof(struct xilinx_spi)); if (!master) return -ENODEV; /* the spi->mode bits understood by this driver: */ master->mode_bits = SPI_CPOL | SPI_CPHA | SPI_LSB_FIRST | SPI_LOOP | SPI_CS_HIGH; xspi = spi_master_get_devdata(master); xspi->cs_inactive = 0xffffffff; xspi->bitbang.master = master; xspi->bitbang.chipselect = xilinx_spi_chipselect; xspi->bitbang.setup_transfer = xilinx_spi_setup_transfer; xspi->bitbang.txrx_bufs = xilinx_spi_txrx_bufs; init_completion(&xspi->done); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); xspi->regs = devm_ioremap_resource(&pdev->dev, res); if (IS_ERR(xspi->regs)) { ret = PTR_ERR(xspi->regs); goto put_master; } master->bus_num = pdev->id; master->num_chipselect = num_cs; master->dev.of_node = pdev->dev.of_node; /* * Detect endianess on the IP via loop bit in CR. Detection * must be done before reset is sent because incorrect reset * value generates error interrupt. * Setup little endian helper functions first and try to use them * and check if bit was correctly setup or not. */ xspi->read_fn = xspi_read32; xspi->write_fn = xspi_write32; xspi->write_fn(XSPI_CR_LOOP, xspi->regs + XSPI_CR_OFFSET); tmp = xspi->read_fn(xspi->regs + XSPI_CR_OFFSET); tmp &= XSPI_CR_LOOP; if (tmp != XSPI_CR_LOOP) { xspi->read_fn = xspi_read32_be; xspi->write_fn = xspi_write32_be; } master->bits_per_word_mask = SPI_BPW_MASK(bits_per_word); xspi->bytes_per_word = bits_per_word / 8; xspi->buffer_size = xilinx_spi_find_buffer_size(xspi); xspi->irq = platform_get_irq(pdev, 0); if (xspi->irq < 0 && xspi->irq != -ENXIO) { ret = xspi->irq; goto put_master; } else if (xspi->irq >= 0) { /* Register for SPI Interrupt */ ret = devm_request_irq(&pdev->dev, xspi->irq, xilinx_spi_irq, 0, dev_name(&pdev->dev), xspi); if (ret) goto put_master; } /* SPI controller initializations */ xspi_init_hw(xspi); ret = spi_bitbang_start(&xspi->bitbang); if (ret) { dev_err(&pdev->dev, "spi_bitbang_start FAILED\n"); goto put_master; } dev_info(&pdev->dev, "at 0x%08llX mapped to 0x%p, irq=%d\n", (unsigned long long)res->start, xspi->regs, xspi->irq); if (pdata) { for (i = 0; i < pdata->num_devices; i++) spi_new_device(master, pdata->devices + i); } platform_set_drvdata(pdev, master); return 0; put_master: spi_master_put(master); return ret; }
static void spi_lm70llp_attach(struct parport *p) { struct pardevice *pd; struct spi_lm70llp *pp; struct spi_master *master; int status; if (lm70llp) { printk(KERN_WARNING "%s: spi_lm70llp instance already loaded. Aborting.\n", DRVNAME); return; } master = spi_alloc_master(p->physport->dev, sizeof *pp); if (!master) { status = -ENOMEM; goto out_fail; } pp = spi_master_get_devdata(master); master->bus_num = -1; master->num_chipselect = 1; pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = lm70_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = lm70_txrx; pp->bitbang.flags = SPI_3WIRE; pp->port = p; pd = parport_register_device(p, DRVNAME, NULL, NULL, NULL, PARPORT_FLAG_EXCL, pp); if (!pd) { status = -ENOMEM; goto out_free_master; } pp->pd = pd; status = parport_claim(pd); if (status < 0) goto out_parport_unreg; status = spi_bitbang_start(&pp->bitbang); if (status < 0) { printk(KERN_WARNING "%s: spi_bitbang_start failed with status %d\n", DRVNAME, status); goto out_off_and_release; } strcpy(pp->info.modalias, "lm70"); pp->info.max_speed_hz = 6 * 1000 * 1000; pp->info.chip_select = 0; pp->info.mode = SPI_3WIRE | SPI_MODE_0; parport_write_data(pp->port, lm70_INIT); pp->info.controller_data = pp; pp->spidev_lm70 = spi_new_device(pp->bitbang.master, &pp->info); if (pp->spidev_lm70) dev_dbg(&pp->spidev_lm70->dev, "spidev_lm70 at %s\n", dev_name(&pp->spidev_lm70->dev)); else { printk(KERN_WARNING "%s: spi_new_device failed\n", DRVNAME); status = -ENODEV; goto out_bitbang_stop; } pp->spidev_lm70->bits_per_word = 8; lm70llp = pp; return; out_bitbang_stop: spi_bitbang_stop(&pp->bitbang); out_off_and_release: parport_write_data(pp->port, 0); mdelay(10); parport_release(pp->pd); out_parport_unreg: parport_unregister_device(pd); out_free_master: (void) spi_master_put(master); out_fail: pr_info("%s: spi_lm70llp probe fail, status %d\n", DRVNAME, status); }
static void butterfly_attach(struct parport *p) { struct pardevice *pd; int status; struct butterfly *pp; struct spi_master *master; struct device *dev = p->physport->dev; if (butterfly || !dev) return; master = spi_alloc_master(dev, sizeof *pp); if (!master) { status = -ENOMEM; goto done; } pp = spi_master_get_devdata(master); master->bus_num = 42; master->num_chipselect = 2; pp->bitbang.master = spi_master_get(master); pp->bitbang.chipselect = butterfly_chipselect; pp->bitbang.txrx_word[SPI_MODE_0] = butterfly_txrx_word_mode0; pp->port = p; pd = parport_register_device(p, "spi_butterfly", NULL, NULL, NULL, 0 , pp); if (!pd) { status = -ENOMEM; goto clean0; } pp->pd = pd; status = parport_claim(pd); if (status < 0) goto clean1; pr_debug("%s: powerup/reset Butterfly\n", p->name); parport_frob_control(pp->port, spi_cs_bit, 0); pp->lastbyte |= vcc_bits; parport_write_data(pp->port, pp->lastbyte); msleep(5); pp->lastbyte |= butterfly_nreset; parport_write_data(pp->port, pp->lastbyte); msleep(100); status = spi_bitbang_start(&pp->bitbang); if (status < 0) goto clean2; pp->info[0].max_speed_hz = 15 * 1000 * 1000; strcpy(pp->info[0].modalias, "mtd_dataflash"); pp->info[0].platform_data = &flash; pp->info[0].chip_select = 1; pp->info[0].controller_data = pp; pp->dataflash = spi_new_device(pp->bitbang.master, &pp->info[0]); if (pp->dataflash) pr_debug("%s: dataflash at %s\n", p->name, dev_name(&pp->dataflash->dev)); pr_info("%s: AVR Butterfly\n", p->name); butterfly = pp; return; clean2: parport_write_data(pp->port, 0); parport_release(pp->pd); clean1: parport_unregister_device(pd); clean0: (void) spi_master_put(pp->bitbang.master); done: pr_debug("%s: butterfly probe, fail %d\n", p->name, status); }