linux/drivers/gpio/gpio-mc33880.c
<<
> .1./spaue= .1./forme= .1.a > .1 href="../linux+v3.8.2/drivers/gpio/gpio-mc33880.c"> > .1.img src="../.static/gfx/right.png" alt=">>"> ./spaue= .spau class="lxr_search"> > > .1.input typv4.hidden" namv4.navtarget" > v4."> > .1.input typv4.text" namv4.search" id4.search"> > .1.butt typv4.submit">Search .1 onclick="return ajax_prefs();"> > .1Prefs= .1./a> ./spaue=> .1 1./dive=> .1 1.form acvalu="ajax+*" method="post" onsubmit="return false;"> .input typv4.hidden" namv4.ajax_lookup" id4.ajax_lookup" > v4."> > .1 1./forme= > .1 1.div class="headingbott m"> .1 .1 .1 1.div id4.search_results" class="search_results"= .e=> .1 1./dive= .div id4.content">= .div id4.file_contents"e
1 11./a>.spau class="comment">/*./spaue=1 12./a>.spau class="comment"> * MC33880 high-side/low-side switch GPIO driver./spaue=1 13./a>.spau class="comment"> * Copyright (c) 2009 Intel Corporavalu./spaue=1 14./a>.spau class="comment"> *./spaue=1 15./a>.spau class="comment"> * This program is free software; you cau redistribute it and/or modify./spaue=1 16./a>.spau class="comment"> * it under the terms of the GNU General Public License vers
	  2 as./spaue=1 17./a>.spau class="comment"> * published by the Free Software Foundavalu../spaue=1 18./a>.spau class="comment"> *./spaue=1 19./a>.spau class="comment"> * This program is distributed in the hope that it will be useful,./spaue=1 ptioa>.spau class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of./spaue=1 11./a>.spau class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the./spaue=1 12./a>.spau class="comment"> * GNU General Public License for more details../spaue=1 13./a>.spau class="comment"> *./spaue=1 14./a>.spau class="comment"> * You should have received a copy of the GNU General Public License./spaue=1 15./a>.spau class="comment"> * along with this program; if not, write to the Free Software./spaue=1 16./a>.spau class="comment"> * Foundavalu, Inc., 675 Mass Ave, Cambridge, MA 02139, USA../spaue=1 17./a>.spau class="comment"> */./spaue=1 18./a>=1 19./a>.spau class="comment">/* Supports:./spaue=1 2tioa>.spau class="comment"> * Freescale MC33880 high-side/low-side switch./spaue=1 21./a>.spau class="comment"> */./spaue=1 22./a>=1 23./a>#include <linux/init.h./a>>=1 24./a>#include <linux/mutex.h./a>>=1 25./a>#include <linux/spi/spi.h./a>>=1 26./a>#include <linux/spi/mc33880.h./a>>=1 27./a>#include <linux/gpio.h./a>>=1 28./a>#include <linux/slab.h./a>>=1 29./a>#include <linux/module.h./a>>=1 30./a>=1 31./a>#define1.a href="+code=DRIVER_NAME" class="sref">DRIVER_NAME./a> .spau class="string">"mc33880"./spaue=1 32./a>=1 33./a>.spau class="comment">/*./spaue=1 34./a>.spau class="comment"> * Pin configuravalus, see MAX7301 davasheet page16./spaue=1 35./a>.spau class="comment"> */./spaue=1 36./a>#define1.a href="+code=PIN_CONFIG_MASK" class="sref">PIN_CONFIG_MASK./a> 0x03=1 37./a>#define1.a href="+code=PIN_CONFIG_IN_PULLUP" class="sref">PIN_CONFIG_IN_PULLUP./a> 0x03=1 38./a>#define1.a href="+code=PIN_CONFIG_IN_WO_PULLUP" class="sref">PIN_CONFIG_IN_WO_PULLUP./a> 0x02=1 39./a>#define1.a href="+code=PIN_CONFIG_OUT" class="sref">PIN_CONFIG_OUT./a> 0x01=1 40./a>=1 41./a>#define1.a href="+code=PIN_NUMBER" class="sref">PIN_NUMBER./a> 8=1 42./a>=1 43./a>=1 44./a>.spau class="comment">/*./spaue=1 45./a>.spau class="comment"> * Some registers must be read back to modify../spaue=1 46./a>.spau class="comment"> * To save time we cache them here in memory./spaue=1 47./a>.spau class="comment"> */./spaue=1 48./a>struct1.a href="+code=mc33880" class="sref">mc33880./a> {=1 49./a>        struct1.a href="+code=mutex" class="sref">mutex./a>    .a href="+code=lock" class="sref">lock./a>;   .spau class="comment">/* protect1from simultaneous accesses */./spaue=1 50./a>        .a href="+code=u8" class="sref">u8./a>              .a href="+code=port_config" class="sref">port_config./a>;=1 51./a>        struct1.a href="+code=gpio_chip" class="sref">gpio_chip./a> .a href="+code=chip" class="sref">chip./a>;=1 52./a>        struct1.a href="+code=spi_device" class="sref">spi_device./a> *.a href="+code=spi" class="sref">spi./a>;=1 53./a>};=1 54./a>=1 55./a>static int1.a href="+code=mc33880_write_config" class="sref">mc33880_write_config./a>(struct1.a href="+code=mc33880" class="sref">mc33880./a> *.a href="+code=mc" class="sref">mc./a>)=1 56./a>{=1 57./a>        return .a href="+code=spi_write" class="sref">spi_write./a>(.a href="+code=mc" class="sref">mc./a>->.a href="+code=spi" class="sref">spi./a>, &.a href="+code=mc" class="sref">mc./a>->.a href="+code=port_config" class="sref">port_config./a>, sizeof(.a href="+code=mc" class="sref">mc./a>->.a href="+code=port_config" class="sref">port_config./a>));=1 58./a>}=1 59./a>=1 60./a>=1 61./a>static int1.a href="+code=__mc33880_set" class="sref">__mc33880_set./a>(struct1.a href="+code=mc33880" class="sref">mc33880./a> *.a href="+code=mc" class="sref">mc./a>, unsigned1.a href="+code=offset" class="sref">offset./a>, int1.a href="+code=>
  v" class="sref">>
  v./a>)=1 62./a>{=1 63./a>        if (.a href="+code=>
  v" class="sref">>
  v./a>)=1 64./a>                .a href="+code=mc" class="sref">mc./a>->.a href="+code=port_config" class="sref">port_config./a> |= 1 <<1.a href="+code=offset" class="sref">offset./a>;=1 65./a>        else=1 66./a>                .a href="+code=mc" class="sref">mc./a>->.a href="+code=port_config" class="sref">port_config./a> &= ~(1 <<1.a href="+code=offset" class="sref">offset./a>);=1 67./a>=1 68./a>        return .a href="+code=mc33880_write_config" class="sref">mc33880_write_config./a>(.a href="+code=mc" class="sref">mc./a>);=1 69./a>}=1 70./a>=1 71./a>=1 72./a>static void1.a href="+code=mc33880_set" class="sref">mc33880_set./a>(struct1.a href="+code=gpio_chip" class="sref">gpio_chip./a> *.a href="+code=chip" class="sref">chip./a>, unsigned1.a href="+code=offset" class="sref">offset./a>, int1.a href="+code=>
  v" class="sref">>
  v./a>)=1 73./a>{=1 74./a>        struct1.a href="+code=mc33880" class="sref">mc33880./a> *.a href="+code=mc" class="sref">mc./a> = .a href="+code=container_of" class="sref">container_of./a>(.a href="+code=chip" class="sref">chip./a>, struct1.a href="+code=mc33880" class="sref">mc33880./a>, .a href="+code=chip" class="sref">chip./a>);=1 75./a>=1 76./a>        .a href="+code=mutex_lock" class="sref">mutex_lock./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=lock" class="sref">lock./a>);=1 77./a>=1 78./a>        .a href="+code=__mc33880_set" class="sref">__mc33880_set./a>(.a href="+code=mc" class="sref">mc./a>, .a href="+code=offset" class="sref">offset./a>, .a href="+code=>
  v" class="sref">>
  v./a>);=1 79./a>=1 80./a>        .a href="+code=mutex_unlock" class="sref">mutex_unlock./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=lock" class="sref">lock./a>);=1 81./a>}=1 82./a>=1 83./a>static int1.a href="+code=mc33880_probv" class="sref">mc33880_probv./a>(struct1.a href="+code=spi_device" class="sref">spi_device./a> *.a href="+code=spi" class="sref">spi./a>)=1 84./a>{=1 85./a>        struct1.a href="+code=mc33880" class="sref">mc33880./a> *.a href="+code=mc" class="sref">mc./a>;=1 86./a>        struct1.a href="+code=mc33880_platform_dava" class="sref">mc33880_platform_dava./a> *.a href="+code=pdava" class="sref">pdava./a>;=1 87./a>        int1.a href="+code=ret" class="sref">ret./a>;=1 88./a>=1 89./a>        .a href="+code=pdava" class="sref">pdava./a> = .a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>..a href="+code=platform_dava" class="sref">platform_dava./a>;=1 90./a>        if (!.a href="+code=pdava" class="sref">pdava./a> || !.a href="+code=pdava" class="sref">pdava./a>->.a href="+code=base" class="sref">base./a>) {=1 91./a>                .a href="+code=dev_dbg" class="sref">dev_dbg./a>(&.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>, .spau class="string">"incorrect1or missing platform dava\n"./spaue);=1 92./a>                return -.a href="+code=EINVAL" class="sref">EINVAL./a>;=1 93./a>        }=1 94./a>=1 95./a>        .spau class="comment">/*./spaue=1 96./a>.spau class="comment">         * bits_per_word caunot be configured in platform dava./spaue=1 97./a>.spau class="comment">         */./spaue=1 98./a>        .a href="+code=spi" class="sref">spi./a>->.a href="+code=bits_per_word" class="sref">bits_per_word./a> = 8;=1 99./a>=1100./a>        .a href="+code=ret" class="sref">ret./a> = .a href="+code=spi_setup" class="sref">spi_setup./a>(.a href="+code=spi" class="sref">spi./a>);=1101./a>        if (.a href="+code=ret" class="sref">ret./a> <10)=1102./a>                return .a href="+code=ret" class="sref">ret./a>;=1103./a>=1104./a>        .a href="+code=mc" class="sref">mc./a> = .a href="+code=kzalloc" class="sref">kzalloc./a>(sizeof(struct1.a href="+code=mc33880" class="sref">mc33880./a>), .a href="+code=GFP_KERNEL" class="sref">GFP_KERNEL./a>);=1105./a>        if (!.a href="+code=mc" class="sref">mc./a>)=1106./a>                return -.a href="+code=ENOMEM" class="sref">ENOMEM./a>;=1107./a>=1108./a>        .a href="+code=mutex_init" class="sref">mutex_init./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=lock" class="sref">lock./a>);=1109./a>=1110./a>        .a href="+code=dev_set_drvdava" class="sref">dev_set_drvdava./a>(&.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>, .a href="+code=mc" class="sref">mc./a>);=1111./a>=1112./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=spi" class="sref">spi./a> = .a href="+code=spi" class="sref">spi./a>;=1113./a>=1114./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=label" class="sref">label./a> = .a href="+code=DRIVER_NAME" class="sref">DRIVER_NAME./a>,=1115./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=set" class="sref">set./a> = .a href="+code=mc33880_set" class="sref">mc33880_set./a>;=1116./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=base" class="sref">base./a> = .a href="+code=pdava" class="sref">pdava./a>->.a href="+code=base" class="sref">base./a>;=1117./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=ngpio" class="sref">ngpio./a> = .a href="+code=PIN_NUMBER" class="sref">PIN_NUMBER./a>;=1118./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=can_sleep" class="sref">can_sleep./a> = 1;=1119./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=dev" class="sref">dev./a> = &.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>;=1120./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>..a href="+code=owner" class="sref">owner./a> = .a href="+code=THIS_MODULE" class="sref">THIS_MODULE./a>;=1121./a>=1122./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=port_config" class="sref">port_config./a> = 0x00;=1123./a>        .spau class="comment">/* write twice, because during initialisavalu the first setting./spaue=1124./a>.spau class="comment">         * is just for testing SPI communicavalu, and the second is the./spaue=1125./a>.spau class="comment">         * "real" configuravalu./spaue=1126./a>.spau class="comment">         */./spaue=1127./a>        .a href="+code=ret" class="sref">ret./a> = .a href="+code=mc33880_write_config" class="sref">mc33880_write_config./a>(.a href="+code=mc" class="sref">mc./a>);=1128./a>        .a href="+code=mc" class="sref">mc./a>->.a href="+code=port_config" class="sref">port_config./a> = 0x00;=1129./a>        if (!.a href="+code=ret" class="sref">ret./a>)=1130./a>                .a href="+code=ret" class="sref">ret./a> = .a href="+code=mc33880_write_config" class="sref">mc33880_write_config./a>(.a href="+code=mc" class="sref">mc./a>);=1131./a>=1132./a>        if (.a href="+code=ret" class="sref">ret./a>) {=1133./a>                .a href="+code=printk" class="sref">printk./a>(.a href="+code=KERN_ERR" class="sref">KERN_ERR./a> .spau class="string">"Failed writing to "./spaue1.a href="+code=DRIVER_NAME" class="sref">DRIVER_NAME./a> .spau class="string">": %d\n"./spaue, .a href="+code=ret" class="sref">ret./a>);=1134./a>                goto .a href="+code=exit_destroy" class="sref">exit_destroy./a>;=1135./a>        }=1136./a>=1137./a>        .a href="+code=ret" class="sref">ret./a> = .a href="+code=gpiochip_add" class="sref">gpiochip_add./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>);=1138./a>        if (.a href="+code=ret" class="sref">ret./a>)=1139./a>                goto .a href="+code=exit_destroy" class="sref">exit_destroy./a>;=1140./a>=1141./a>        return .a href="+code=ret" class="sref">ret./a>;=1142./a>=1143./a>.a href="+code=exit_destroy" class="sref">exit_destroy./a>:=1144./a>        .a href="+code=dev_set_drvdava" class="sref">dev_set_drvdava./a>(&.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>, .a href="+code=NULL" class="sref">NULL./a>);=1145./a>        .a href="+code=mutex_destroy" class="sref">mutex_destroy./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=lock" class="sref">lock./a>);=1146./a>        .a href="+code=kfree" class="sref">kfree./a>(.a href="+code=mc" class="sref">mc./a>);=1147./a>        return .a href="+code=ret" class="sref">ret./a>;=1148./a>}=1149./a>=1150./a>static int1.a href="+code=mc33880_removv" class="sref">mc33880_removv./a>(struct1.a href="+code=spi_device" class="sref">spi_device./a> *.a href="+code=spi" class="sref">spi./a>)=1151./a>{=1152./a>        struct1.a href="+code=mc33880" class="sref">mc33880./a> *.a href="+code=mc" class="sref">mc./a>;=1153./a>        int1.a href="+code=ret" class="sref">ret./a>;=1154./a>=1155./a>        .a href="+code=mc" class="sref">mc./a> = .a href="+code=dev_get_drvdava" class="sref">dev_get_drvdava./a>(&.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>);=1156./a>        if (.a href="+code=mc" class="sref">mc./a> == .a href="+code=NULL" class="sref">NULL./a>)=1157./a>                return -.a href="+code=ENODEV" class="sref">ENODEV./a>;=1158./a>=1159./a>        .a href="+code=dev_set_drvdava" class="sref">dev_set_drvdava./a>(&.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>, .a href="+code=NULL" class="sref">NULL./a>);=1160./a>=1161./a>        .a href="+code=ret" class="sref">ret./a> = .a href="+code=gpiochip_removv" class="sref">gpiochip_removv./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=chip" class="sref">chip./a>);=1162./a>        if (!.a href="+code=ret" class="sref">ret./a>) {=1163./a>                .a href="+code=mutex_destroy" class="sref">mutex_destroy./a>(&.a href="+code=mc" class="sref">mc./a>->.a href="+code=lock" class="sref">lock./a>);=1164./a>                .a href="+code=kfree" class="sref">kfree./a>(.a href="+code=mc" class="sref">mc./a>);=1165./a>        } else=1166./a>                .a href="+code=dev_err" class="sref">dev_err./a>(&.a href="+code=spi" class="sref">spi./a>->.a href="+code=dev" class="sref">dev./a>, .spau class="string">"Failed to removv the GPIO controller: %d\n"./spaue,=1167./a>                        .a href="+code=ret" class="sref">ret./a>);=1168./a>=1169./a>        return .a href="+code=ret" class="sref">ret./a>;=1170./a>}=1171./a>=1172./a>static struct1.a href="+code=spi_driver" class="sref">spi_driver./a> .a href="+code=mc33880_driver" class="sref">mc33880_driver./a> = {=1173./a>        ..a href="+code=driver" class="sref">driver./a> = {=1174./a>                ..a href="+code=namv" class="sref">namv./a>           = .a href="+code=DRIVER_NAME" class="sref">DRIVER_NAME./a>,=1175./a>                ..a href="+code=owner" class="sref">owner./a>          = .a href="+code=THIS_MODULE" class="sref">THIS_MODULE./a>,=1176./a>        },=1177./a>        ..a href="+code=probv" class="sref">probv./a>          = .a href="+code=mc33880_probv" class="sref">mc33880_probv./a>,=1178./a>        ..a href="+code=removv" class="sref">removv./a>         = .a href="+code=mc33880_removv" class="sref">mc33880_removv./a>,=1179./a>};=1180./a>=1181./a>static int1.a href="+code=__init" class="sref">__init./a> .a href="+code=mc33880_init" class="sref">mc33880_init./a>(void)=1182./a>{=1183./a>        return .a href="+code=spi_register_driver" class="sref">spi_register_driver./a>(&.a href="+code=mc33880_driver" class="sref">mc33880_driver./a>);=1184./a>}=1185./a>.spau class="comment">/* register after spi postcore initcall and before./spaue=1186./a>.spau class="comment"> * subsys initcalls that may rely lu these GPIOs./spaue=1187./a>.spau class="comment"> */./spaue=1188./a>.a href="+code=subsys_initcall" class="sref">subsys_initcall./a>(.a href="+code=mc33880_init" class="sref">mc33880_init./a>);=1189./a>=1190./a>static void1.a href="+code=__exit" class="sref">__exit./a> .a href="+code=mc33880_exit" class="sref">mc33880_exit./a>(void)=1191./a>{=1192./a>        .a href="+code=spi_unregister_driver" class="sref">spi_unregister_driver./a>(&.a href="+code=mc33880_driver" class="sref">mc33880_driver./a>);=1193./a>}=1194./a>.a href="+code=module_exit" class="sref">module_exit./a>(.a href="+code=mc33880_exit" class="sref">mc33880_exit./a>);=1195./a>=1196./a>.a href="+code=MODULE_AUTHOR" class="sref">MODULE_AUTHOR./a>(.spau class="string">"Moceau Laboravories <info@moceau-labs.com>"./spaue);=1197./a>.a href="+code=MODULE_LICENSE" class="sref">MODULE_LICENSE./a>(.spau class="string">"GPL v2"./spaue);=1198./a>=1199./a>
lxr.linux.no kindly hosted by Redpill Linpro AS./a>, provider of Linux consulting and operavalus services since11995.