From Gopal_Sukumar at mindtree.com Thu Apr 1 00:37:08 2010 From: Gopal_Sukumar at mindtree.com (Gopal Sukumar) Date: Thu, 1 Apr 2010 12:07:08 +0530 Subject: JVM on DaVinci In-Reply-To: <30776573.210741270042725028.JavaMail.root@email> References: <30776573.210741270042725028.JavaMail.root@email> Message-ID: <4BB43F14.6050302@mindtree.com> Thank you Mark. Even I was wondering if this was apt. Regards, Gopal Sukumar. Mark Deneen wrote: > SpiderMonkey is JavaScript, similar in name only to Java. > > Best Regards, > Mark Deneen > Saucon Technologies > > Best Regards, > Mark Deneen > Saucon Technologies > > ----- "Arie Muijnck" wrote: > > >> SpiderMonkey works fine. >> >> Kind regards, >> Arie de Muijnck >> >> >> >> From: davinci-linux-open-source-bounces at linux.davincidsp.com >> [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On >> Behalf Of Gopal Sukumar >> Sent: Wednesday, March 31, 2010 09:17 >> To: DaVinciMailingList >> Subject: JVM on DaVinci >> >> >> >> Dear all, >> >> Can we run JVM on DaVinci platforms? I would like to develop code in >> Java to run on DaVinci. Is this possible? >> >> Thanks in advance. >> >> Regards >> Gopal Sukumar. >> >> >> >> http://www.mindtree.com/email/disclaimer.html >> >> This message contains confidential information and is intended only >> for the individual named. If you are not the named addressee you >> should not disseminate, distribute or copy this e-mail. Please notify >> the sender immediately by e-mail if you have received this e-mail by >> mistake and delete this e-mail from your system. E-mail transmission >> cannot be guaranteed to be secure or error-free as information could >> be intercepted, corrupted, lost, destroyed, arrive late or incomplete, >> or contain viruses. The sender therefore does not accept liability for >> any errors or omissions in the contents of this message, which arise >> as a result of e-mail transmission. If verification is required please >> request a hard-copy version. >> >> Please consider the environment before printing this email message >> -------------- next part -------------- An HTML attachment was scrubbed... URL: From Jon.Povey at racelogic.co.uk Thu Apr 1 00:47:40 2010 From: Jon.Povey at racelogic.co.uk (Jon Povey) Date: Thu, 1 Apr 2010 07:47:40 +0100 Subject: [PATCH v2] DA8XX/OMAP-L1XX: FB: Implement double buffering In-Reply-To: <20100331203256.852450d3.akpm@linux-foundation.org> Message-ID: <70E876B0EA86DD4BAF101844BC814DFE0FDD0EFE@Cloud.RL.local> Andrew Morton wrote: > On Wed, 31 Mar 2010 20:43:29 -0500 "Ambrose, Martin" > wrote: >>> If the calling process has signal_pending() (say, someone hit ^C) >>> then wait_event_interruptible_timeout() will fall straight through >>> with -ERESTARTSYS. Will this cause the driver to malfunction at >>> all? >> >> I don't think so since the driver doesn't make use of this >> information in any way. This is just status to the caller that the >> current frame has finished DMA'ing out of the framebuffer. >> >> Could you maybe propose a scenario/use case where you think it is >> problematic? I could then either reason why it should be OK or >> I'll create a test harness and see how the driver can/should be >> modified. > > Gee, I dunno - I don't understand the driver to that level. If you're > OK with this wait being interrupted by a signal and the driver handles > it OK then fine, that's a feature. > > To test it I suppose you should give your test app a signal handler > and blast kills at it from another process. Jumping in.. This should not cause a problem for the driver; its purpose is to tell userland that it can write to the buffer without corrupting graphics (as presumably it is double-buffering and the other buffer is now being DMA'd from by the hardware). At worst, if the userland software doesn't handle this correctly it may draw one bad frame of graphics. Although if it's had a ctrl-C it probably has bigger things to worry about. If the app wants to handle signals it needs to consider such things.. I would not expect the driver to do anything other than what this patch does. -- Jon Povey jon.povey at racelogic.co.uk Racelogic is a limited company registered in England. Registered number 2743719 . Registered Office Unit 10, Swan Business Centre, Osier Way, Buckingham, Bucks, MK18 1TB . The information contained in this electronic mail transmission is intended by Racelogic Ltd for the use of the named individual or entity to which it is directed and may contain information that is confidential or privileged. If you have received this electronic mail transmission in error, please delete it from your system without copying or forwarding it, and notify the sender of the error by reply email so that the sender's address records can be corrected. The views expressed by the sender of this communication do not necessarily represent those of Racelogic Ltd. Please note that Racelogic reserves the right to monitor e-mail communications passing through its network From Priya_Raghavendra at mindtree.com Thu Apr 1 02:49:04 2010 From: Priya_Raghavendra at mindtree.com (Priya Raghavendra) Date: Thu, 1 Apr 2010 14:19:04 +0530 Subject: Unable the detect SD card after kernel boot up on DM6467 Message-ID: <1B3CA99331DE5E47BB89385002F8D1EF110A45ADC5@MTW02MSG02.mindtree.com> Hi, I am working on a custom board which has TI Davinci DM6467 Processor running Linux 2.6.10 as the host processor to which we have a USB2640 hub controller connected on the USB bus. This hub controller has a built in SD card controller. So basically this hub supports two USB devices and one SD card. The problem I am facing right now is that if the SD card is connected during kernel boot up, the SD card gets detected and also enumerated. After this I am able to mount the SD card. But in case I plug in the SD card after kernel boot up, the SD card does not get detected when I insert it. The USB devices like USB pen drive or mouse connected to the USB ports are detected when they are hot plugged. So how do I enable hot plugging for the SD card? Basically how do I enumerate the SD card once the kernel is up and the SD card is hot plugged? Thanks, bkrpri ________________________________ http://www.mindtree.com/email/disclaimer.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From gasparini at imavis.com Thu Apr 1 02:54:58 2010 From: gasparini at imavis.com (Andrea Gasparini) Date: Thu, 1 Apr 2010 10:54:58 +0200 Subject: JVM on DaVinci In-Reply-To: References: <4BB2F6DD.70406@mindtree.com> Message-ID: <201004011054.59116.gasparini@imavis.com> Ben Gardiner spiffera, alle Wednesday 31 March 2010 circa: > On Wed, Mar 31, 2010 at 3:16 AM, Gopal Sukumar > > wrote: > > Dear all, > > > > Can we run JVM on DaVinci platforms? I would like to develop code in > > Java to run on DaVinci. Is this possible? > > You definitely can. GCJ comes to mind. Oracle/Sun's Java SE for > embedded is an option > http://java.sun.com/javase/downloads/embedded.jsp. I think that > openjdk is also a possibility but I haven't used it personally. just for curiosity: does a JVM that supports Jazelle extensions exist? given that Davinci processors has them, why can't we use it? :P bye! -- Andrea Gasparini ---- ImaVis S.r.l. ---- web: www.imavis.com From tarkandogu at gmail.com Thu Apr 1 03:00:09 2010 From: tarkandogu at gmail.com (Tarkan DOGU) Date: Thu, 1 Apr 2010 12:00:09 +0300 Subject: 6446 Master Volume Control Message-ID: I am trying to control master volume on 6446. But during the IOCTL phase I am getting error -1. My Linux version is OE(Open Embedded - Angstrom) Do u have any idea? Thanks inadvance... B.R Tarkan int DeviceSound,vol=0; if ((DeviceSound = open("/dev/pcmC0D0c", O_RDWR)) == -1) { printf("Failed to open /dev/pcmC0D0c\n"); return -1; } if (ioctl(DeviceSound, SOUND_MIXER_WRITE_VOLUME, &vol) == -1) { printf("Failed to set DeviceSound for vol.\n"); close(DeviceSound); return -1; -------------- next part -------------- An HTML attachment was scrubbed... URL: From Gopal_Sukumar at mindtree.com Thu Apr 1 03:28:54 2010 From: Gopal_Sukumar at mindtree.com (Gopal Sukumar) Date: Thu, 1 Apr 2010 14:58:54 +0530 Subject: JVM on DaVinci In-Reply-To: <201004011054.59116.gasparini@imavis.com> References: <4BB2F6DD.70406@mindtree.com> <201004011054.59116.gasparini@imavis.com> Message-ID: <4BB46756.5020607@mindtree.com> This was the first thing I asked when my Technology Head inquired about 'JVM on DaVinci. :) Andrea Gasparini wrote: Ben Gardiner spiffera, alle Wednesday 31 March 2010 circa: On Wed, Mar 31, 2010 at 3:16 AM, Gopal Sukumar wrote: Dear all, Can we run JVM on DaVinci platforms? I would like to develop code in Java to run on DaVinci. Is this possible? You definitely can. GCJ comes to mind. Oracle/Sun's Java SE for embedded is an option http://java.sun.com/javase/downloads/embedded.jsp. I think that openjdk is also a possibility but I haven't used it personally. just for curiosity: does a JVM that supports Jazelle extensions exist? given that Davinci processors has them, why can't we use it? :P bye! ________________________________ http://www.mindtree.com/email/disclaimer.html -------------- next part -------------- An HTML attachment was scrubbed... URL: From pratik.joshi at einfochips.com Thu Apr 1 04:43:28 2010 From: pratik.joshi at einfochips.com (Pratik Joshi) Date: Thu, 1 Apr 2010 16:13:28 +0530 Subject: Query -USB hub with multiple block devices connected Message-ID: <006201cad188$2c8a9ec0$859fdc40$@joshi@einfochips.com> Hi All, I am getting following error while I run Wireless USB device and a mass storage device together. This error is displayed on console continuously and I have to reboot the DVEVM. ++++++++++++++++++++++++++++++++++ SCSI error : <0 0 0 0> return code = 0x70000 end_request: I/O error, dev sda, sector 4404236 ------------------------------------------------------------- Regards, Pratik Joshi Embedded Engineer eInfochips Ltd, Ahmedabad, India +91-079-26563705 - ext - 303 www.einfochips.com From: Pratik Joshi [mailto:pratik.joshi at einfochips.com] Sent: Tuesday, March 30, 2010 6:26 PM To: 'davinci-linux-open-source at linux.davincidsp.com' Subject: Query -USB hub with multiple block devices connected Hi All, We are seeing following problem: Setup: We have connected a USB hub to DVEVM. We have connected two bulk devices mass storage and USB wireless device. We are continuously receiving data on USB wireless device (using iperf utility) and at the same time continuously writing to mass storage device. We do fsync () after writing data using write command to ensure data is actually written to mass storage device. Problem statement: In above setup we see SCSI errors and I/O errors. Also we have observed "usb 1-1.1: usb_sg_cancel, unlink --> 0" message sometimes. What is the significance of this message? Has anyone tested USB driver in such a driver? Regards, Pratik Joshi Embedded Engineer eInfochips Ltd, Ahmedabad, India +91-079-26563705 - ext - 303 www.einfochips.com -- _____________________________________________________________________ Disclaimer: This e-mail message and all attachments transmitted with it are intended solely for the use of the addressee and may contain legally privileged and confidential information. If the reader of this message is not the intended recipient, or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution, copying, or other use of this message or its attachments is strictly prohibited. If you have received this message in error, please notify the sender immediately by replying to this message and please delete it from your computer. Any views expressed in this message are those of the individual sender unless otherwise stated.Company has taken enough precautions to prevent the spread of viruses. However the company accepts no liability for any damage caused by any virus transmitted by this email. _____________________________________________________________________ -------------- next part -------------- An HTML attachment was scrubbed... URL: From scerveau at awox.com Thu Apr 1 06:30:28 2010 From: scerveau at awox.com (Stephane Cerveau) Date: Thu, 1 Apr 2010 14:30:28 +0200 Subject: Query -USB hub with multiple block devices connected References: <006201cad188$2c8a9ec0$859fdc40$@joshi@einfochips.com> Message-ID: <46423D9081D5254CAFCEFF0CBC2CC9BA021BFFB8@jakarta.awox.com> Hi all, I experienced the same bug and I succeed to workaround the bug by adding a delay into musb_ep_program but this is working only with the RT73 USB Wireless device. I experienced bug with other Wireless device. Joshi, you can I think the verbose level in the musb driver. May be it can help you to diagnose the bug with more accuracy... Any comment or help will be welcome. Stephane From: Pratik Joshi [mailto:pratik.joshi at einfochips.com] Sent: jeudi 1 avril 2010 12:43 To: davinci-linux-open-source at linux.davincidsp.com Subject: RE: Query -USB hub with multiple block devices connected Hi All, I am getting following error while I run Wireless USB device and a mass storage device together. This error is displayed on console continuously and I have to reboot the DVEVM. ++++++++++++++++++++++++++++++++++ SCSI error : <0 0 0 0> return code = 0x70000 end_request: I/O error, dev sda, sector 4404236 ------------------------------------------------------------- Regards, Pratik Joshi Embedded Engineer eInfochips Ltd, Ahmedabad, India +91-079-26563705 - ext - 303 www.einfochips.com From: Pratik Joshi [mailto:pratik.joshi at einfochips.com] Sent: Tuesday, March 30, 2010 6:26 PM To: 'davinci-linux-open-source at linux.davincidsp.com' Subject: Query -USB hub with multiple block devices connected Hi All, We are seeing following problem: Setup: We have connected a USB hub to DVEVM. We have connected two bulk devices mass storage and USB wireless device. We are continuously receiving data on USB wireless device (using iperf utility) and at the same time continuously writing to mass storage device. We do fsync () after writing data using write command to ensure data is actually written to mass storage device. Problem statement: In above setup we see SCSI errors and I/O errors. Also we have observed "usb 1-1.1: usb_sg_cancel, unlink --> 0" message sometimes. What is the significance of this message? Has anyone tested USB driver in such a driver? Regards, Pratik Joshi Embedded Engineer eInfochips Ltd, Ahmedabad, India +91-079-26563705 - ext - 303 www.einfochips.com -- _____ Disclaimer: This e-mail message and all attachments transmitted with it are intended solely for the use of the addressee and may contain legally privileged and confidential information. If the reader of this message is not the intended recipient, or an employee or agent responsible for delivering this message to the intended recipient, you are hereby notified that any dissemination, distribution, copying, or other use of this message or its attachments is strictly prohibited. If you have received this message in error, please notify the sender immediately by replying to this message and please delete it from your computer. Any views expressed in this message are those of the individual sender unless otherwise stated.Company has taken enough precautions to prevent the spread of viruses. However the company accepts no liability for any damage caused by any virus transmitted by this email. _____ __________ Information from ESET NOD32 Antivirus, version of virus signature database 4991 (20100401) __________ The message was checked by ESET NOD32 Antivirus. http://www.eset.com -------------- next part -------------- An HTML attachment was scrubbed... URL: From mchehab at redhat.com Thu Apr 1 10:20:39 2010 From: mchehab at redhat.com (Mauro Carvalho Chehab) Date: Thu, 01 Apr 2010 13:20:39 -0300 Subject: [GIT FIX for 2.6.34] V4L - vpfe capture - fix for kernel crash on DM365 In-Reply-To: <55a3e0ce1003270613k1d565204qfe51a5f746439701@mail.gmail.com> References: <1268846327-7255-1-git-send-email-m-karicheri2@ti.com> <4BAA6CF8.4060006@redhat.com> <55a3e0ce1003270613k1d565204qfe51a5f746439701@mail.gmail.com> Message-ID: <4BB4C7D7.2000304@redhat.com> Muralidharan Karicheri wrote: > Mauro, > > When I had last replied to your email, I didn't check if the patch is > actually applied to your v4l_for_linux branch of fixes.git tree. But > Today I checked and I can't find the patch merged to this tree as you > had mentioned.. > > So if you haven't merged it for some reason, please merge my updated patch > available at https://patchwork.kernel.org/patch/86731/ > I had merged, but, as I haven't pushed on linuxtv, I decided to rebase my local tree. Patch applied. -- Cheers, Mauro From m-karicheri2 at ti.com Thu Apr 1 10:29:38 2010 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Thu, 1 Apr 2010 11:29:38 -0500 Subject: [GIT FIX for 2.6.34] V4L - vpfe capture - fix for kernel crash on DM365 In-Reply-To: <4BB4C7D7.2000304@redhat.com> References: <1268846327-7255-1-git-send-email-m-karicheri2@ti.com> <4BAA6CF8.4060006@redhat.com> <55a3e0ce1003270613k1d565204qfe51a5f746439701@mail.gmail.com> <4BB4C7D7.2000304@redhat.com> Message-ID: Mauro, Thanks a lot for your support. Do you plan to merge my pull request for 2.6.35 anytime soon? Murali Karicheri Software Design Engineer Texas Instruments Inc. Germantown, MD 20874 phone: 301-407-9583 email: m-karicheri2 at ti.com >-----Original Message----- >From: Mauro Carvalho Chehab [mailto:mchehab at redhat.com] >Sent: Thursday, April 01, 2010 12:21 PM >To: Muralidharan Karicheri >Cc: Karicheri, Muralidharan; linux-media at vger.kernel.org; >hverkuil at xs4all.nl; davinci-linux-open-source at linux.davincidsp.com >Subject: Re: [GIT FIX for 2.6.34] V4L - vpfe capture - fix for kernel crash >on DM365 > >Muralidharan Karicheri wrote: >> Mauro, >> >> When I had last replied to your email, I didn't check if the patch is >> actually applied to your v4l_for_linux branch of fixes.git tree. But >> Today I checked and I can't find the patch merged to this tree as you >> had mentioned.. >> >> So if you haven't merged it for some reason, please merge my updated >patch >> available at https://patchwork.kernel.org/patch/86731/ >> > >I had merged, but, as I haven't pushed on linuxtv, I decided to rebase my >local >tree. Patch applied. > >-- > >Cheers, >Mauro From lamiaposta71 at gmail.com Thu Apr 1 10:31:16 2010 From: lamiaposta71 at gmail.com (Raffaele Recalcati) Date: Thu, 1 Apr 2010 18:31:16 +0200 Subject: dm365 - voice codec Message-ID: It seems that in git kernel this peripheral is not yet supported. I search everywere: ./arch/arm/mach-davinci/dm365.c: CLK("davinci_voicecodec", NULL, &voicecodec_clk), ./arch/arm/mach-davinci/dm365.c: .name = "davinci_voicecodec", This means that davinci_voicecodec is not really configured. Anybody can please confirm this point and tell me the development roadmap? Thx, Raffaele From mchehab at redhat.com Thu Apr 1 10:35:33 2010 From: mchehab at redhat.com (Mauro Carvalho Chehab) Date: Thu, 01 Apr 2010 13:35:33 -0300 Subject: [GIT FIX for 2.6.34] V4L - vpfe capture - fix for kernel crash on DM365 In-Reply-To: References: <1268846327-7255-1-git-send-email-m-karicheri2@ti.com> <4BAA6CF8.4060006@redhat.com> <55a3e0ce1003270613k1d565204qfe51a5f746439701@mail.gmail.com> <4BB4C7D7.2000304@redhat.com> Message-ID: <4BB4CB55.8060503@redhat.com> Karicheri, Muralidharan wrote: > Mauro, > > Thanks a lot for your support. > > Do you plan to merge my pull request for 2.6.35 anytime soon? It were already merged locally. I'm running a compilation of the tree with the merged patches. If all compile ok, your pull request (and others) will be at linuxtv server soon. -- Cheers, Mauro From richard.salvetat at arbos-dsp.com Thu Apr 1 10:48:48 2010 From: richard.salvetat at arbos-dsp.com (Richard SALVETAT) Date: Thu, 1 Apr 2010 18:48:48 +0200 Subject: cancel my inscription Message-ID: <20100401164847.66AA38000367@mwinf2f24.orange.fr> Please stop my incripstion on the mail list -------------- next part -------------- An HTML attachment was scrubbed... URL: From m-karicheri2 at ti.com Thu Apr 1 12:08:54 2010 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Thu, 1 Apr 2010 13:08:54 -0500 Subject: isif - debugging on dm365 In-Reply-To: References: Message-ID: Raffaele, [MK] 0 means the interrupt happens right at VD pulse. 1 means after one line. You might want to check the signals received from ADV to input of VPFE to see if adv is doing what it is configured to do. My colleague has found how to make the vpfe_isr interrupt working with adv7180. He has made this change in isif.c inside isif_config_ycbcr: - ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR; + ccdcfg = ccdcfg | ISIF_DATA_PACK8 ; [MK] What you are doing is essentially swapping the Y and C input lines. Probably on your board, you are connecting the input differently than on the DM365 evm. Please confirm if this is the only change that got it working. He verified that tvp514x was really working using 10bit port. If he disabled pinmux on Y0 and Y1 interrupts aren't generated. But in isif_config_ycbcr function the kernel enters in case VPFE_BT656: because it lacks a call for setting isif_cfg.if_type. I think the problem is that the YCINSWP setting on your board. In 8 bit mode, this decides whether input signals are connected to Y input or C input. In TVP5146 on DM365, it is connected to C input, where as on your board it is connected to Y input. So we need to add this as a configurable variable in the board setup file, read it and set in isif.c. Please send a patch to the list. For example define a variable y_c_swap and set it to 0 in your board. On DM365 evm board file you can set it to 1 so that it works fine for tvp5146 and adv7180. In isif.c you can read this variable and update the YCINSWP bit in CCDCFG. Are you planning to send a patch for this? Murali -------------- next part -------------- An HTML attachment was scrubbed... URL: From m-karicheri2 at ti.com Thu Apr 1 12:12:13 2010 From: m-karicheri2 at ti.com (Karicheri, Muralidharan) Date: Thu, 1 Apr 2010 13:12:13 -0500 Subject: isif - debugging on dm365 In-Reply-To: References: Message-ID: Some typo corrected.... Murali Karicheri Software Design Engineer Texas Instruments Inc. Germantown, MD 20874 phone: 301-407-9583 email: m-karicheri2 at ti.com ________________________________ From: davinci-linux-open-source-bounces at linux.davincidsp.com [mailto:davinci-linux-open-source-bounces at linux.davincidsp.com] On Behalf Of Karicheri, Muralidharan Sent: Thursday, April 01, 2010 2:09 PM To: Raffaele Recalcati Cc: davinci-linux-open-source Subject: RE: isif - debugging on dm365 Raffaele, [MK] 0 means the interrupt happens right at VD pulse. 1 means after one line. You might want to check the signals received from ADV to input of VPFE to see if adv is doing what it is configured to do. My colleague has found how to make the vpfe_isr interrupt working with adv7180. He has made this change in isif.c inside isif_config_ycbcr: - ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR; + ccdcfg = ccdcfg | ISIF_DATA_PACK8 ; [MK] What you are doing is essentially swapping the Y and C input lines. Probably on your board, you are connecting the input differently than on the DM365 evm. Please confirm if this is the only change that got it working. He verified that tvp514x was really working using 10bit port. If he disabled pinmux on Y0 and Y1 interrupts aren't generated. But in isif_config_ycbcr function the kernel enters in case VPFE_BT656: because it lacks a call for setting isif_cfg.if_type. I think the problem is in the YCINSWP setting on your board. In 8 bit mode, this decides whether input signals are connected to Y input or C input as per data sheet. In TVP5146 on DM365 evm, it is connected to C input and hence we set that bit, where as on your board it is connected to Y input. So we need to add this as a configurable variable in the board setup file, read it and set in isif.c. Please send a patch to the list. For example define a variable y_c_swap and set it to 0 in your board. On DM365 evm board file you can set it to 1 so that it works fine for both tvp5146 and adv7180. In isif.c you can read this variable and update the YCINSWP bit in CCDCFG. Murali -------------- next part -------------- An HTML attachment was scrubbed... URL: From lamiaposta71 at gmail.com Fri Apr 2 00:38:04 2010 From: lamiaposta71 at gmail.com (Raffaele Recalcati) Date: Fri, 2 Apr 2010 08:38:04 +0200 Subject: isif - debugging on dm365 In-Reply-To: References: Message-ID: I ll send a patch tuesday. Today i am on holyday 2010/4/1, Karicheri, Muralidharan : > Raffaele, > > [MK] 0 means the interrupt happens right at VD pulse. 1 means after one > line. You might want to check the signals received from ADV to input of VPFE > to see if adv is doing what it is configured to do. > > My colleague has found how to make the vpfe_isr interrupt working with > adv7180. > He has made this change in isif.c inside isif_config_ycbcr: > > - ccdcfg = ccdcfg | ISIF_DATA_PACK8 | ISIF_YCINSWP_YCBCR; > + ccdcfg = ccdcfg | ISIF_DATA_PACK8 ; > [MK] What you are doing is essentially swapping the Y and C input lines. > Probably on your board, you are connecting the input differently than on the > DM365 evm. Please confirm if this is the only change that got it working. > He verified that tvp514x was really working using 10bit port. > If he disabled pinmux on Y0 and Y1 interrupts aren't generated. > But in isif_config_ycbcr function the kernel enters in > case VPFE_BT656: > because it lacks a call for setting isif_cfg.if_type. > I think the problem is that the YCINSWP setting on your board. In 8 bit > mode, this decides whether input signals are connected to Y input or C > input. In TVP5146 on DM365, it is connected to C input, where as on your > board it is connected to Y input. So we need to add this as a configurable > variable in the board setup file, read it and set in isif.c. Please send a > patch to the list. For example define a variable y_c_swap and set it to 0 in > your board. On DM365 evm board file you can set it to 1 so that it works > fine for tvp5146 and adv7180. In isif.c you can read this variable and > update the YCINSWP bit in CCDCFG. Are you planning to send a patch for this? > Murali > > > > > > > -- www.opensurf.it From a.auer at zydacron.com Fri Apr 2 02:58:15 2010 From: a.auer at zydacron.com (Andreas Auer) Date: Fri, 02 Apr 2010 10:58:15 +0200 Subject: DM6446 and DSA (Distributed Switch Architecture) In-Reply-To: References: Message-ID: Steve Chen schrieb: > On Wed, Mar 31, 2010 at 2:44 AM, Andreas Auer wrote: >> Hello, >> >> I'm using a customized board similar to the EVM with a DM6446 cpu. The main >> difference is that I'm using a Micrel KSZ8893M ethernet switch. The ethernet >> switch has an I2C config interface and the standard mdio interface. >> Therefore, I'm using the DSA driver subsystem and wrote a small chip driver >> (I took the KSZ8893 driver for the Blackfin processor as reference). >> Now, my problem is that the ethernet mac of the Davinci cpu is initialized >> (probed) later then the DSA driver. And therefore the DSA driver cannot find >> a valid netdevice. >> Does anyone know how to change the initialization order of the devices?? >> Changing the order of the register_device_driver function calls has >> basically no influence on the init sequence. >> >> Thanks, >> Andreas > > Hello, > > I encounter the same issue with DA830/OMAP-l137 EVM. Instead of > probing PHY to get speed and duplexity, the driver just set the speed > and duplexity based on platform data. May want to take a look at the > OMAP-l137. Thanks for your answer. I got another solution. The davinci_emac driver calls the init function very late because of late_initcall(davinci_emac_init); I changed this line: module_init(davinci_emac_init); Now, it is working! Cheers, Andreas From albertbu at gmail.com Fri Apr 2 08:12:26 2010 From: albertbu at gmail.com (Albert Burbea) Date: Fri, 2 Apr 2010 16:12:26 +0200 Subject: video port for omap Message-ID: hi guys can somebody pls explain me how to configure the mistral board kernel (arago kernel) to use a specific video sensor (non standard one) 10x in advance -- Albert Burbea Mobile: +972-52-3541842 -------------- next part -------------- An HTML attachment was scrubbed... URL: From todd.fischer at ridgerun.com Fri Apr 2 15:33:44 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Fri, 02 Apr 2010 15:33:44 -0600 Subject: [PATCH 0/4]-V2 TPS6507x MFD driver In-Reply-To: <1269634292-29686-1-git-send-email-todd.fischer@ridgerun.com> References: <1269634292-29686-1-git-send-email-todd.fischer@ridgerun.com> Message-ID: <1270244024.20290.8603.camel@sax-lx> This is the second posting of the TPS6507x driver set. I have incorporated Mark Brown's feedback and retested. Patches 3 and 5 have been combined so there are only 4 patches in the series now. The TPS6507x family of Texas Instruments power management ICs (pmic) are multi-function chips that include voltage regulation and touch screen controller capabilities. This patch set adds a TPS6507x multi-function device driver and change the TPS6507x regulator driver to use the TPS6507x MFD driver instead of interacting with the chip directly. The changes are needed before a touch screen driver can be added. The patch set applies cleanly to the MFD repository: git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git If the MFD and voltage regulator maintainer would prefer I post patches for a different repository, please let me know. The TPS6507x touch screen input driver will be posted to linux-input at vger.kernel.org list. From todd.fischer at ridgerun.com Fri Apr 2 15:37:29 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Fri, 2 Apr 2010 15:37:29 -0600 Subject: [PATCH 0/4]-V2 TPS6507x MFD driver Message-ID: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> This is the second posting of the TPS6507x driver set. I have incorporated Mark Brown's feedback and retested. Patches 3 and 5 have been combined so there are only 4 patches in the series now. The TPS6507x family of Texas Instruments power management ICs (pmic) are multi-function chips that include voltage regulation and touch screen controller capabilities. This patch set adds a TPS6507x multi-function device driver and change the TPS6507x regulator driver to use the TPS6507x MFD driver instead of interacting with the chip directly. The changes are needed before a touch screen driver can be added. The patch set applies cleanly to the MFD repository: git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6.git If the MFD and voltage regulator maintainer would prefer I post patches for a different repository, please let me know. The TPS6507x touch screen input driver will be posted to linux-input at vger.kernel.org list. From todd.fischer at ridgerun.com Fri Apr 2 15:37:30 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Fri, 2 Apr 2010 15:37:30 -0600 Subject: [PATCH 1/4]-V2 Move TPS6507x register definition to header file. In-Reply-To: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> Message-ID: <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> Other sub-drivers for the TPS6507x chip will need to use register definition so move it out of the source file and into a header file. Signed-off-by: Todd Fischer --- drivers/regulator/tps6507x-regulator.c | 60 +-------------- include/linux/mfd/tps6507x.h | 134 ++++++++++++++++++++++++++++++++ 2 files changed, 135 insertions(+), 59 deletions(-) create mode 100644 include/linux/mfd/tps6507x.h diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index c2a9539..91172e3 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -24,65 +24,7 @@ #include #include #include - -/* Register definitions */ -#define TPS6507X_REG_PPATH1 0X01 -#define TPS6507X_REG_INT 0X02 -#define TPS6507X_REG_CHGCONFIG0 0X03 -#define TPS6507X_REG_CHGCONFIG1 0X04 -#define TPS6507X_REG_CHGCONFIG2 0X05 -#define TPS6507X_REG_CHGCONFIG3 0X06 -#define TPS6507X_REG_REG_ADCONFIG 0X07 -#define TPS6507X_REG_TSCMODE 0X08 -#define TPS6507X_REG_ADRESULT_1 0X09 -#define TPS6507X_REG_ADRESULT_2 0X0A -#define TPS6507X_REG_PGOOD 0X0B -#define TPS6507X_REG_PGOODMASK 0X0C -#define TPS6507X_REG_CON_CTRL1 0X0D -#define TPS6507X_REG_CON_CTRL2 0X0E -#define TPS6507X_REG_CON_CTRL3 0X0F -#define TPS6507X_REG_DEFDCDC1 0X10 -#define TPS6507X_REG_DEFDCDC2_LOW 0X11 -#define TPS6507X_REG_DEFDCDC2_HIGH 0X12 -#define TPS6507X_REG_DEFDCDC3_LOW 0X13 -#define TPS6507X_REG_DEFDCDC3_HIGH 0X14 -#define TPS6507X_REG_DEFSLEW 0X15 -#define TPS6507X_REG_LDO_CTRL1 0X16 -#define TPS6507X_REG_DEFLDO2 0X17 -#define TPS6507X_REG_WLED_CTRL1 0X18 -#define TPS6507X_REG_WLED_CTRL2 0X19 - -/* CON_CTRL1 bitfields */ -#define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) -#define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) -#define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) -#define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) -#define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) - -/* DEFDCDC1 bitfields */ -#define TPS6507X_DEFDCDC1_DCDC1_EXT_ADJ_EN BIT(7) -#define TPS6507X_DEFDCDC1_DCDC1_MASK 0X3F - -/* DEFDCDC2_LOW bitfields */ -#define TPS6507X_DEFDCDC2_LOW_DCDC2_MASK 0X3F - -/* DEFDCDC2_HIGH bitfields */ -#define TPS6507X_DEFDCDC2_HIGH_DCDC2_MASK 0X3F - -/* DEFDCDC3_LOW bitfields */ -#define TPS6507X_DEFDCDC3_LOW_DCDC3_MASK 0X3F - -/* DEFDCDC3_HIGH bitfields */ -#define TPS6507X_DEFDCDC3_HIGH_DCDC3_MASK 0X3F - -/* TPS6507X_REG_LDO_CTRL1 bitfields */ -#define TPS6507X_REG_LDO_CTRL1_LDO1_MASK 0X0F - -/* TPS6507X_REG_DEFLDO2 bitfields */ -#define TPS6507X_REG_DEFLDO2_LDO2_MASK 0X3F - -/* VDCDC MASK */ -#define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F +#include /* DCDC's */ #define TPS6507X_DCDC_1 0 diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h new file mode 100644 index 0000000..155bee1 --- /dev/null +++ b/include/linux/mfd/tps6507x.h @@ -0,0 +1,134 @@ +/* linux/mfd/tps6507x.h + * + * Functions to access TPS65070 power management chip. + * + * Copyright (c) 2009 RidgeRun (todd.fischer at ridgerun.com) + * + * + * For licencing details see kernel-base/COPYING + */ + +#ifndef __LINUX_MFD_TPS6507X_H +#define __LINUX_MFD_TPS6507X_H + +/* + * ---------------------------------------------------------------------------- + * Registers, all 8 bits + * ---------------------------------------------------------------------------- + */ + + +/* Register definitions */ +#define TPS6507X_REG_PPATH1 0X01 +#define TPS6507X_CHG_USB BIT(7) +#define TPS6507X_CHG_AC BIT(6) +#define TPS6507X_CHG_USB_PW_ENABLE BIT(5) +#define TPS6507X_CHG_AC_PW_ENABLE BIT(4) +#define TPS6507X_CHG_AC_CURRENT BIT(2) +#define TPS6507X_CHG_USB_CURRENT BIT(0) + +#define TPS6507X_REG_INT 0X02 +#define TPS6507X_REG_MASK_AC_USB BIT(7) +#define TPS6507X_REG_MASK_TSC BIT(6) +#define TPS6507X_REG_MASK_PB_IN BIT(5) +#define TPS6507X_REG_TSC_INT BIT(3) +#define TPS6507X_REG_PB_IN_INT BIT(2) +#define TPS6507X_REG_AC_USB_APPLIED BIT(1) +#define TPS6507X_REG_AC_USB_REMOVED BIT(0) + +#define TPS6507X_REG_CHGCONFIG0 0X03 + +#define TPS6507X_REG_CHGCONFIG1 0X04 +#define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) +#define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) +#define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) +#define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) +#define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) + +#define TPS6507X_REG_CHGCONFIG2 0X05 + +#define TPS6507X_REG_CHGCONFIG3 0X06 + +#define TPS6507X_REG_ADCONFIG 0X07 +#define TPS6507X_ADCONFIG_AD_ENABLE BIT(7) +#define TPS6507X_ADCONFIG_START_CONVERSION BIT(6) +#define TPS6507X_ADCONFIG_CONVERSION_DONE BIT(5) +#define TPS6507X_ADCONFIG_VREF_ENABLE BIT(4) +#define TPS6507X_ADCONFIG_INPUT_AD_IN1 0 +#define TPS6507X_ADCONFIG_INPUT_AD_IN2 1 +#define TPS6507X_ADCONFIG_INPUT_AD_IN3 2 +#define TPS6507X_ADCONFIG_INPUT_AD_IN4 3 +#define TPS6507X_ADCONFIG_INPUT_TS_PIN 4 +#define TPS6507X_ADCONFIG_INPUT_BAT_CURRENT 5 +#define TPS6507X_ADCONFIG_INPUT_AC_VOLTAGE 6 +#define TPS6507X_ADCONFIG_INPUT_SYS_VOLTAGE 7 +#define TPS6507X_ADCONFIG_INPUT_CHARGER_VOLTAGE 8 +#define TPS6507X_ADCONFIG_INPUT_BAT_VOLTAGE 9 +#define TPS6507X_ADCONFIG_INPUT_THRESHOLD_VOLTAGE 10 +#define TPS6507X_ADCONFIG_INPUT_ISET1_VOLTAGE 11 +#define TPS6507X_ADCONFIG_INPUT_ISET2_VOLTAGE 12 +#define TPS6507X_ADCONFIG_INPUT_REAL_TSC 14 +#define TPS6507X_ADCONFIG_INPUT_TSC 15 + +#define TPS6507X_REG_TSCMODE 0X08 +#define TPS6507X_TSCMODE_X_POSITION 0 +#define TPS6507X_TSCMODE_Y_POSITION 1 +#define TPS6507X_TSCMODE_PRESSURE 2 +#define TPS6507X_TSCMODE_X_PLATE 3 +#define TPS6507X_TSCMODE_Y_PLATE 4 +#define TPS6507X_TSCMODE_STANDBY 5 +#define TPS6507X_TSCMODE_ADC_INPUT 6 +#define TPS6507X_TSCMODE_DISABLE 7 + +#define TPS6507X_REG_ADRESULT_1 0X09 + +#define TPS6507X_REG_ADRESULT_2 0X0A +#define TPS6507X_REG_ADRESULT_2_MASK (BIT(1) | BIT(0)) + +#define TPS6507X_REG_PGOOD 0X0B + +#define TPS6507X_REG_PGOODMASK 0X0C + +#define TPS6507X_REG_CON_CTRL1 0X0D +#define TPS6507X_CON_CTRL1_DCDC1_ENABLE BIT(4) +#define TPS6507X_CON_CTRL1_DCDC2_ENABLE BIT(3) +#define TPS6507X_CON_CTRL1_DCDC3_ENABLE BIT(2) +#define TPS6507X_CON_CTRL1_LDO1_ENABLE BIT(1) +#define TPS6507X_CON_CTRL1_LDO2_ENABLE BIT(0) + +#define TPS6507X_REG_CON_CTRL2 0X0E + +#define TPS6507X_REG_CON_CTRL3 0X0F + +#define TPS6507X_REG_DEFDCDC1 0X10 +#define TPS6507X_DEFDCDC1_DCDC1_EXT_ADJ_EN BIT(7) +#define TPS6507X_DEFDCDC1_DCDC1_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC2_LOW 0X11 +#define TPS6507X_DEFDCDC2_LOW_DCDC2_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC2_HIGH 0X12 +#define TPS6507X_DEFDCDC2_HIGH_DCDC2_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC3_LOW 0X13 +#define TPS6507X_DEFDCDC3_LOW_DCDC3_MASK 0X3F + +#define TPS6507X_REG_DEFDCDC3_HIGH 0X14 +#define TPS6507X_DEFDCDC3_HIGH_DCDC3_MASK 0X3F + +#define TPS6507X_REG_DEFSLEW 0X15 + +#define TPS6507X_REG_LDO_CTRL1 0X16 +#define TPS6507X_REG_LDO_CTRL1_LDO1_MASK 0X0F + +#define TPS6507X_REG_DEFLDO2 0X17 +#define TPS6507X_REG_DEFLDO2_LDO2_MASK 0X3F + +#define TPS6507X_REG_WLED_CTRL1 0X18 + +#define TPS6507X_REG_WLED_CTRL2 0X19 + +/* VDCDC MASK */ +#define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F + +#endif /* __LINUX_MFD_TPS6507X_H */ -- 1.6.0.4 From todd.fischer at ridgerun.com Fri Apr 2 15:37:31 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Fri, 2 Apr 2010 15:37:31 -0600 Subject: [PATCH 2/4]-V2 Make room for other tps6507x drivers to have board specific initialization data. In-Reply-To: <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> Message-ID: <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> Add mfd structure which refrences sub-driver initialization data. For example, for a giving hardware implementation, the voltage regulator sub-driver initialization data provides the mapping betten a voltage regulator and what the output voltage is being used for. Signed-off-by: Todd Fischer --- arch/arm/mach-davinci/board-da850-evm.c | 7 ++++++- drivers/regulator/tps6507x-regulator.c | 14 ++++++++++++-- include/linux/mfd/tps6507x.h | 11 +++++++++++ 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index 411284d..d059924 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -533,10 +534,14 @@ struct regulator_init_data tps65070_regulator_data[] = { }, }; +static struct tps6507x_board tps_board = { + .tps6507x_pmic_init_data = &tps65070_regulator_data[0], +}; + static struct i2c_board_info __initdata da850evm_tps65070_info[] = { { I2C_BOARD_INFO("tps6507x", 0x48), - .platform_data = &tps65070_regulator_data[0], + .platform_data = &tps_board, }, }; diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 91172e3..becf652 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -488,6 +488,7 @@ static int __devinit tps_6507x_probe(struct i2c_client *client, struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps_pmic *tps; + struct tps6507x_board *tps_board; int i; int error; @@ -496,12 +497,21 @@ static int __devinit tps_6507x_probe(struct i2c_client *client, return -EIO; /** + * tps_board points to pmic related constants + * coming from the board-evm file. + */ + + tps_board = dev_get_platdata(&client->dev); + if (!tps_board) + return -EINVAL; + + /** * init_data points to array of regulator_init structures * coming from the board-evm file. */ - init_data = client->dev.platform_data; + init_data = tps_board->tps6507x_pmic_init_data; if (!init_data) - return -EIO; + return -EINVAL; tps = kzalloc(sizeof(*tps), GFP_KERNEL); if (!tps) diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index 155bee1..fd73af5 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -131,4 +131,15 @@ /* VDCDC MASK */ #define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F +/** + * struct tps6507x_board - packages regulator and touchscreen init data + * @tps6507x_regulator_data: regulator initialization values + * + * Board data may be used to initialize regulator and touchscreen. + */ + +struct tps6507x_board { + struct regulator_init_data *tps6507x_pmic_init_data; +}; + #endif /* __LINUX_MFD_TPS6507X_H */ -- 1.6.0.4 From todd.fischer at ridgerun.com Fri Apr 2 15:37:32 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Fri, 2 Apr 2010 15:37:32 -0600 Subject: [PATCH 3/4]-V2 Cleaned up name space so each MFD sub-driver uses a different name space. In-Reply-To: <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> Message-ID: <1270244253-4234-4-git-send-email-todd.fischer@ridgerun.com> Move from using tps or tsp6507x to tps6057x_pmic in a consistent manner. Signed-off-by: Todd Fischer --- drivers/regulator/tps6507x-regulator.c | 172 ++++++++++++++++---------------- 1 files changed, 87 insertions(+), 85 deletions(-) diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index becf652..86f2e05 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -103,7 +103,7 @@ struct tps_info { const u16 *table; }; -struct tps_pmic { +struct tps6507x_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; struct i2c_client *client; struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; @@ -111,23 +111,23 @@ struct tps_pmic { struct mutex io_lock; }; -static inline int tps_6507x_read(struct tps_pmic *tps, u8 reg) +static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg) { return i2c_smbus_read_byte_data(tps->client, reg); } -static inline int tps_6507x_write(struct tps_pmic *tps, u8 reg, u8 val) +static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val) { return i2c_smbus_write_byte_data(tps->client, reg, val); } -static int tps_6507x_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) +static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) { int err, data; mutex_lock(&tps->io_lock); - data = tps_6507x_read(tps, reg); + data = tps6507x_pmic_read(tps, reg); if (data < 0) { dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); err = data; @@ -135,7 +135,7 @@ static int tps_6507x_set_bits(struct tps_pmic *tps, u8 reg, u8 mask) } data |= mask; - err = tps_6507x_write(tps, reg, data); + err = tps6507x_pmic_write(tps, reg, data); if (err) dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); @@ -144,13 +144,13 @@ out: return err; } -static int tps_6507x_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) +static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) { int err, data; mutex_lock(&tps->io_lock); - data = tps_6507x_read(tps, reg); + data = tps6507x_pmic_read(tps, reg); if (data < 0) { dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); err = data; @@ -158,7 +158,7 @@ static int tps_6507x_clear_bits(struct tps_pmic *tps, u8 reg, u8 mask) } data &= ~mask; - err = tps_6507x_write(tps, reg, data); + err = tps6507x_pmic_write(tps, reg, data); if (err) dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); @@ -167,13 +167,13 @@ out: return err; } -static int tps_6507x_reg_read(struct tps_pmic *tps, u8 reg) +static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg) { int data; mutex_lock(&tps->io_lock); - data = tps_6507x_read(tps, reg); + data = tps6507x_pmic_read(tps, reg); if (data < 0) dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); @@ -181,13 +181,13 @@ static int tps_6507x_reg_read(struct tps_pmic *tps, u8 reg) return data; } -static int tps_6507x_reg_write(struct tps_pmic *tps, u8 reg, u8 val) +static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val) { int err; mutex_lock(&tps->io_lock); - err = tps_6507x_write(tps, reg, val); + err = tps6507x_pmic_write(tps, reg, val); if (err < 0) dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); @@ -195,9 +195,9 @@ static int tps_6507x_reg_write(struct tps_pmic *tps, u8 reg, u8 val) return err; } -static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) +static int tps6507x_pmic_dcdc_is_enabled(struct regulator_dev *dev) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, dcdc = rdev_get_id(dev); u8 shift; @@ -205,7 +205,7 @@ static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) return -EINVAL; shift = TPS6507X_MAX_REG_ID - dcdc; - data = tps_6507x_reg_read(tps, TPS6507X_REG_CON_CTRL1); + data = tps6507x_pmic_reg_read(tps, TPS6507X_REG_CON_CTRL1); if (data < 0) return data; @@ -213,9 +213,9 @@ static int tps6507x_dcdc_is_enabled(struct regulator_dev *dev) return (data & 1<info[dcdc]->table[data] * 1000; } -static int tps6507x_dcdc_set_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_dcdc_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, vsel, dcdc = rdev_get_id(dev); u8 reg; @@ -352,19 +354,19 @@ static int tps6507x_dcdc_set_voltage(struct regulator_dev *dev, if (vsel == tps->info[dcdc]->table_len) return -EINVAL; - data = tps_6507x_reg_read(tps, reg); + data = tps6507x_pmic_reg_read(tps, reg); if (data < 0) return data; data &= ~TPS6507X_DEFDCDCX_DCDC_MASK; data |= vsel; - return tps_6507x_reg_write(tps, reg, data); + return tps6507x_pmic_reg_write(tps, reg, data); } -static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) +static int tps6507x_pmic_ldo_get_voltage(struct regulator_dev *dev) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, ldo = rdev_get_id(dev); u8 reg, mask; @@ -378,7 +380,7 @@ static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) TPS6507X_REG_DEFLDO2_LDO2_MASK); } - data = tps_6507x_reg_read(tps, reg); + data = tps6507x_pmic_reg_read(tps, reg); if (data < 0) return data; @@ -386,10 +388,10 @@ static int tps6507x_ldo_get_voltage(struct regulator_dev *dev) return tps->info[ldo]->table[data] * 1000; } -static int tps6507x_ldo_set_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_ldo_set_voltage(struct regulator_dev *dev, int min_uV, int max_uV) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int data, vsel, ldo = rdev_get_id(dev); u8 reg, mask; @@ -420,20 +422,20 @@ static int tps6507x_ldo_set_voltage(struct regulator_dev *dev, if (vsel == tps->info[ldo]->table_len) return -EINVAL; - data = tps_6507x_reg_read(tps, reg); + data = tps6507x_pmic_reg_read(tps, reg); if (data < 0) return data; data &= ~mask; data |= vsel; - return tps_6507x_reg_write(tps, reg, data); + return tps6507x_pmic_reg_write(tps, reg, data); } -static int tps6507x_dcdc_list_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_dcdc_list_voltage(struct regulator_dev *dev, unsigned selector) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int dcdc = rdev_get_id(dev); if (dcdc < TPS6507X_DCDC_1 || dcdc > TPS6507X_DCDC_3) @@ -445,10 +447,10 @@ static int tps6507x_dcdc_list_voltage(struct regulator_dev *dev, return tps->info[dcdc]->table[selector] * 1000; } -static int tps6507x_ldo_list_voltage(struct regulator_dev *dev, +static int tps6507x_pmic_ldo_list_voltage(struct regulator_dev *dev, unsigned selector) { - struct tps_pmic *tps = rdev_get_drvdata(dev); + struct tps6507x_pmic *tps = rdev_get_drvdata(dev); int ldo = rdev_get_id(dev); if (ldo < TPS6507X_LDO_1 || ldo > TPS6507X_LDO_2) @@ -461,33 +463,33 @@ static int tps6507x_ldo_list_voltage(struct regulator_dev *dev, } /* Operations permitted on VDCDCx */ -static struct regulator_ops tps6507x_dcdc_ops = { - .is_enabled = tps6507x_dcdc_is_enabled, - .enable = tps6507x_dcdc_enable, - .disable = tps6507x_dcdc_disable, - .get_voltage = tps6507x_dcdc_get_voltage, - .set_voltage = tps6507x_dcdc_set_voltage, - .list_voltage = tps6507x_dcdc_list_voltage, +static struct regulator_ops tps6507x_pmic_dcdc_ops = { + .is_enabled = tps6507x_pmic_dcdc_is_enabled, + .enable = tps6507x_pmic_dcdc_enable, + .disable = tps6507x_pmic_dcdc_disable, + .get_voltage = tps6507x_pmic_dcdc_get_voltage, + .set_voltage = tps6507x_pmic_dcdc_set_voltage, + .list_voltage = tps6507x_pmic_dcdc_list_voltage, }; /* Operations permitted on LDOx */ -static struct regulator_ops tps6507x_ldo_ops = { - .is_enabled = tps6507x_ldo_is_enabled, - .enable = tps6507x_ldo_enable, - .disable = tps6507x_ldo_disable, - .get_voltage = tps6507x_ldo_get_voltage, - .set_voltage = tps6507x_ldo_set_voltage, - .list_voltage = tps6507x_ldo_list_voltage, +static struct regulator_ops tps6507x_pmic_ldo_ops = { + .is_enabled = tps6507x_pmic_ldo_is_enabled, + .enable = tps6507x_pmic_ldo_enable, + .disable = tps6507x_pmic_ldo_disable, + .get_voltage = tps6507x_pmic_ldo_get_voltage, + .set_voltage = tps6507x_pmic_ldo_set_voltage, + .list_voltage = tps6507x_pmic_ldo_list_voltage, }; -static int __devinit tps_6507x_probe(struct i2c_client *client, +static int __devinit tps6507x_pmic_probe(struct i2c_client *client, const struct i2c_device_id *id) { static int desc_id; const struct tps_info *info = (void *)id->driver_data; struct regulator_init_data *init_data; struct regulator_dev *rdev; - struct tps_pmic *tps; + struct tps6507x_pmic *tps; struct tps6507x_board *tps_board; int i; int error; @@ -529,7 +531,7 @@ static int __devinit tps_6507x_probe(struct i2c_client *client, tps->desc[i].id = desc_id++; tps->desc[i].n_voltages = num_voltages[i]; tps->desc[i].ops = (i > TPS6507X_DCDC_3 ? - &tps6507x_ldo_ops : &tps6507x_dcdc_ops); + &tps6507x_pmic_ldo_ops : &tps6507x_pmic_dcdc_ops); tps->desc[i].type = REGULATOR_VOLTAGE; tps->desc[i].owner = THIS_MODULE; @@ -559,14 +561,14 @@ fail: } /** - * tps_6507x_remove - TPS6507x driver i2c remove handler + * tps6507x_remove - TPS6507x driver i2c remove handler * @client: i2c driver client device structure * * Unregister TPS driver as an i2c client device driver */ -static int __devexit tps_6507x_remove(struct i2c_client *client) +static int __devexit tps6507x_pmic_remove(struct i2c_client *client) { - struct tps_pmic *tps = i2c_get_clientdata(client); + struct tps6507x_pmic *tps = i2c_get_clientdata(client); int i; /* clear the client data in i2c */ @@ -580,7 +582,7 @@ static int __devexit tps_6507x_remove(struct i2c_client *client) return 0; } -static const struct tps_info tps6507x_regs[] = { +static const struct tps_info tps6507x_pmic_regs[] = { { .name = "VDCDC1", .min_uV = 725000, @@ -618,44 +620,44 @@ static const struct tps_info tps6507x_regs[] = { }, }; -static const struct i2c_device_id tps_6507x_id[] = { +static const struct i2c_device_id tps6507x_pmic_id[] = { {.name = "tps6507x", - .driver_data = (unsigned long) tps6507x_regs,}, + .driver_data = (unsigned long) tps6507x_pmic_regs,}, { }, }; -MODULE_DEVICE_TABLE(i2c, tps_6507x_id); +MODULE_DEVICE_TABLE(i2c, tps6507x_pmic_id); -static struct i2c_driver tps_6507x_i2c_driver = { +static struct i2c_driver tps6507x_i2c_driver = { .driver = { .name = "tps6507x", .owner = THIS_MODULE, }, - .probe = tps_6507x_probe, - .remove = __devexit_p(tps_6507x_remove), - .id_table = tps_6507x_id, + .probe = tps6507x_pmic_probe, + .remove = __devexit_p(tps6507x_pmic_remove), + .id_table = tps6507x_pmic_id, }; /** - * tps_6507x_init + * tps6507x_pmic_init * * Module init function */ -static int __init tps_6507x_init(void) +static int __init tps6507x_pmic_init(void) { - return i2c_add_driver(&tps_6507x_i2c_driver); + return i2c_add_driver(&tps6507x_i2c_driver); } -subsys_initcall(tps_6507x_init); +subsys_initcall(tps6507x_pmic_init); /** - * tps_6507x_cleanup + * tps6507x_pmic_cleanup * * Module exit function */ -static void __exit tps_6507x_cleanup(void) +static void __exit tps6507x_pmic_cleanup(void) { - i2c_del_driver(&tps_6507x_i2c_driver); + i2c_del_driver(&tps6507x_i2c_driver); } -module_exit(tps_6507x_cleanup); +module_exit(tps6507x_pmic_cleanup); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); -- 1.6.0.4 From todd.fischer at ridgerun.com Fri Apr 2 15:37:33 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Fri, 2 Apr 2010 15:37:33 -0600 Subject: [PATCH 4/4]-V2 Add MFD driver for TPS6507x family of multi-function chips and move TPS6507x regulator driver from being stand-alone to using the MFD driver. In-Reply-To: <1270244253-4234-4-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-4-git-send-email-todd.fischer@ridgerun.com> Message-ID: <1270244253-4234-5-git-send-email-todd.fischer@ridgerun.com> Add MFD driver for TPS6507x family of multi-function chips. Move TPS6507x regulator driver from being stand-alone driver to using the MFD TPS6507x driver. Signed-off-by: Todd Fischer --- drivers/mfd/Kconfig | 12 +++ drivers/mfd/Makefile | 3 +- drivers/mfd/tps6507x.c | 145 ++++++++++++++++++++++++++++++ drivers/regulator/tps6507x-regulator.c | 153 +++++++++++++++---------------- include/linux/mfd/tps6507x.h | 22 +++++ 5 files changed, 255 insertions(+), 80 deletions(-) create mode 100644 drivers/mfd/tps6507x.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 2a5a0b7..1e301ad 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -111,6 +111,18 @@ config TPS65010 This driver can also be built as a module. If so, the module will be called tps65010. +config TPS6507X + tristate "TPS6507x Power Management / Touch Screen chips" + select MFD_CORE + depends on I2C + help + If you say yes here you get support for the TPS6507x series of + Power Management / Touch Screen chips. These include voltage + regulators, lithium ion/polymer battery charging, touch screen + and other features that are often used in portable devices. + This driver can also be built as a module. If so, the module + will be called tps6507x. + config MENELAUS bool "Texas Instruments TWL92330/Menelaus PM chip" depends on I2C=y && ARCH_OMAP2 diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 22715ad..2bebc95 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -28,6 +28,7 @@ obj-$(CONFIG_MFD_WM8350_I2C) += wm8350-i2c.o obj-$(CONFIG_MFD_WM8994) += wm8994-core.o obj-$(CONFIG_TPS65010) += tps65010.o +obj-$(CONFIG_TPS6507X) += tps6507x.o obj-$(CONFIG_MENELAUS) += menelaus.o obj-$(CONFIG_TWL4030_CORE) += twl-core.o twl4030-irq.o twl6030-irq.o @@ -62,4 +63,4 @@ obj-$(CONFIG_AB3100_OTP) += ab3100-otp.o obj-$(CONFIG_AB4500_CORE) += ab4500-core.o obj-$(CONFIG_MFD_TIMBERDALE) += timberdale.o obj-$(CONFIG_PMIC_ADP5520) += adp5520.o -obj-$(CONFIG_LPC_SCH) += lpc_sch.o \ No newline at end of file +obj-$(CONFIG_LPC_SCH) += lpc_sch.o diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c new file mode 100644 index 0000000..edda9ff --- /dev/null +++ b/drivers/mfd/tps6507x.c @@ -0,0 +1,145 @@ +/* + * tps6507x.c -- TPS6507x chip family multi-function driver + * + * Copyright (c) 2010 RidgeRun (todd.fischer at ridgerun.com) + * + * Author: Todd Fischer + * todd.fischer at ridgerun.com + * + * Credits: + * + * Using code from wm831x-*.c, Wolfson Microelectronics PLC. + * + * For licencing details see kernel-base/COPYING + * + */ + +#include +#include +#include +#include +#include +#include + +static struct mfd_cell tps6507x_devs[] = { + { + .name = "tps6507x-pmic", + }, +}; + + +static int tps6507x_i2c_read_device(struct tps6507x_dev *tps6507x, char reg, + int bytes, void *dest) +{ + struct i2c_client *i2c = tps6507x->i2c_client; + int ret; + + ret = i2c_master_send(i2c, ®, 1); + if (ret < 0) + return ret; + + ret = i2c_master_recv(i2c, dest, bytes); + if (ret < 0) + return ret; + if (ret != bytes) + return -EIO; + return 0; +} + +static int tps6507x_i2c_write_device(struct tps6507x_dev *tps6507x, char reg, + int bytes, void *src) +{ + struct i2c_client *i2c = tps6507x->i2c_client; + /* we add 1 byte for device register */ + u8 msg[(TPS6507X_MAX_REGISTER << 1) + 1]; + int ret; + + if (bytes > ((TPS6507X_MAX_REGISTER << 1) + 1)) + return -EINVAL; + + msg[0] = reg; + memcpy(&msg[1], src, bytes); + + ret = i2c_master_send(i2c, msg, bytes + 1); + if (ret < 0) + return ret; + if (ret != bytes + 1) + return -EIO; + return 0; +} + +static int tps6507x_i2c_probe(struct i2c_client *i2c, + const struct i2c_device_id *id) +{ + struct tps6507x_dev *tps6507x; + int ret = 0; + + tps6507x = kzalloc(sizeof(struct tps6507x_dev), GFP_KERNEL); + if (tps6507x == NULL) { + kfree(i2c); + return -ENOMEM; + } + + i2c_set_clientdata(i2c, tps6507x); + tps6507x->dev = &i2c->dev; + tps6507x->i2c_client = i2c; + tps6507x->read_dev = tps6507x_i2c_read_device; + tps6507x->write_dev = tps6507x_i2c_write_device; + + ret = mfd_add_devices(tps6507x->dev, -1, + tps6507x_devs, ARRAY_SIZE(tps6507x_devs), + NULL, 0); + + if (ret < 0) + goto err; + + return ret; + +err: + mfd_remove_devices(tps6507x->dev); + kfree(tps6507x); + return ret; +} + +static int tps6507x_i2c_remove(struct i2c_client *i2c) +{ + struct tps6507x_dev *tps6507x = i2c_get_clientdata(i2c); + + mfd_remove_devices(tps6507x->dev); + kfree(tps6507x); + + return 0; +} + +static const struct i2c_device_id tps6507x_i2c_id[] = { + { "tps6507x", 0 }, + { } +}; +MODULE_DEVICE_TABLE(i2c, tps6507x_i2c_id); + + +static struct i2c_driver tps6507x_i2c_driver = { + .driver = { + .name = "tps6507x", + .owner = THIS_MODULE, + }, + .probe = tps6507x_i2c_probe, + .remove = tps6507x_i2c_remove, + .id_table = tps6507x_i2c_id, +}; + +static int __init tps6507x_i2c_init(void) +{ + return i2c_add_driver(&tps6507x_i2c_driver); +} +/* init early so consumer devices can complete system boot */ +subsys_initcall(tps6507x_i2c_init); + +static void __exit tps6507x_i2c_exit(void) +{ + i2c_del_driver(&tps6507x_i2c_driver); +} +module_exit(tps6507x_i2c_exit); + +MODULE_DESCRIPTION("TPS6507x chip family multi-function driver"); +MODULE_LICENSE("GPL"); diff --git a/drivers/regulator/tps6507x-regulator.c b/drivers/regulator/tps6507x-regulator.c index 86f2e05..e4d7d2f 100644 --- a/drivers/regulator/tps6507x-regulator.c +++ b/drivers/regulator/tps6507x-regulator.c @@ -22,7 +22,6 @@ #include #include #include -#include #include #include @@ -103,22 +102,67 @@ struct tps_info { const u16 *table; }; +static const struct tps_info tps6507x_pmic_regs[] = { + { + .name = "VDCDC1", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "VDCDC2", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "VDCDC3", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), + .table = VDCDCx_VSEL_table, + }, + { + .name = "LDO1", + .min_uV = 1000000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(LDO1_VSEL_table), + .table = LDO1_VSEL_table, + }, + { + .name = "LDO2", + .min_uV = 725000, + .max_uV = 3300000, + .table_len = ARRAY_SIZE(LDO2_VSEL_table), + .table = LDO2_VSEL_table, + }, +}; + struct tps6507x_pmic { struct regulator_desc desc[TPS6507X_NUM_REGULATOR]; - struct i2c_client *client; + struct tps6507x_dev *mfd; struct regulator_dev *rdev[TPS6507X_NUM_REGULATOR]; const struct tps_info *info[TPS6507X_NUM_REGULATOR]; struct mutex io_lock; }; - static inline int tps6507x_pmic_read(struct tps6507x_pmic *tps, u8 reg) { - return i2c_smbus_read_byte_data(tps->client, reg); + u8 val; + int err; + + err = tps->mfd->read_dev(tps->mfd, reg, 1, &val); + + if (err) + return err; + + return val; } static inline int tps6507x_pmic_write(struct tps6507x_pmic *tps, u8 reg, u8 val) { - return i2c_smbus_write_byte_data(tps->client, reg, val); + return tps->mfd->write_dev(tps->mfd, reg, 1, &val); } static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) @@ -129,7 +173,7 @@ static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data = tps6507x_pmic_read(tps, reg); if (data < 0) { - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); err = data; goto out; } @@ -137,7 +181,7 @@ static int tps6507x_pmic_set_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data |= mask; err = tps6507x_pmic_write(tps, reg, data); if (err) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); out: mutex_unlock(&tps->io_lock); @@ -152,7 +196,7 @@ static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data = tps6507x_pmic_read(tps, reg); if (data < 0) { - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); err = data; goto out; } @@ -160,7 +204,7 @@ static int tps6507x_pmic_clear_bits(struct tps6507x_pmic *tps, u8 reg, u8 mask) data &= ~mask; err = tps6507x_pmic_write(tps, reg, data); if (err) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); out: mutex_unlock(&tps->io_lock); @@ -175,7 +219,7 @@ static int tps6507x_pmic_reg_read(struct tps6507x_pmic *tps, u8 reg) data = tps6507x_pmic_read(tps, reg); if (data < 0) - dev_err(&tps->client->dev, "Read from reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Read from reg 0x%x failed\n", reg); mutex_unlock(&tps->io_lock); return data; @@ -189,7 +233,7 @@ static int tps6507x_pmic_reg_write(struct tps6507x_pmic *tps, u8 reg, u8 val) err = tps6507x_pmic_write(tps, reg, val); if (err < 0) - dev_err(&tps->client->dev, "Write for reg 0x%x failed\n", reg); + dev_err(tps->mfd->dev, "Write for reg 0x%x failed\n", reg); mutex_unlock(&tps->io_lock); return err; @@ -482,11 +526,12 @@ static struct regulator_ops tps6507x_pmic_ldo_ops = { .list_voltage = tps6507x_pmic_ldo_list_voltage, }; -static int __devinit tps6507x_pmic_probe(struct i2c_client *client, - const struct i2c_device_id *id) +static __devinit +int tps6507x_pmic_probe(struct platform_device *pdev) { + struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); static int desc_id; - const struct tps_info *info = (void *)id->driver_data; + const struct tps_info *info = &tps6507x_pmic_regs[0]; struct regulator_init_data *init_data; struct regulator_dev *rdev; struct tps6507x_pmic *tps; @@ -494,16 +539,12 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, int i; int error; - if (!i2c_check_functionality(client->adapter, - I2C_FUNC_SMBUS_BYTE_DATA)) - return -EIO; - /** * tps_board points to pmic related constants * coming from the board-evm file. */ - tps_board = dev_get_platdata(&client->dev); + tps_board = dev_get_platdata(tps6507x_dev->dev); if (!tps_board) return -EINVAL; @@ -522,7 +563,7 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, mutex_init(&tps->io_lock); /* common for all regulators */ - tps->client = client; + tps->mfd = tps6507x_dev; for (i = 0; i < TPS6507X_NUM_REGULATOR; i++, info++, init_data++) { /* Register the regulators */ @@ -536,10 +577,11 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, tps->desc[i].owner = THIS_MODULE; rdev = regulator_register(&tps->desc[i], - &client->dev, init_data, tps); + tps6507x_dev->dev, init_data, tps); if (IS_ERR(rdev)) { - dev_err(&client->dev, "failed to register %s\n", - id->name); + dev_err(tps6507x_dev->dev, + "failed to register %s regulator\n", + pdev->name); error = PTR_ERR(rdev); goto fail; } @@ -548,7 +590,7 @@ static int __devinit tps6507x_pmic_probe(struct i2c_client *client, tps->rdev[i] = rdev; } - i2c_set_clientdata(client, tps); + tps6507x_dev->pmic = tps; return 0; @@ -566,14 +608,12 @@ fail: * * Unregister TPS driver as an i2c client device driver */ -static int __devexit tps6507x_pmic_remove(struct i2c_client *client) +static int __devexit tps6507x_pmic_remove(struct platform_device *pdev) { - struct tps6507x_pmic *tps = i2c_get_clientdata(client); + struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); + struct tps6507x_pmic *tps = tps6507x_dev->pmic; int i; - /* clear the client data in i2c */ - i2c_set_clientdata(client, NULL); - for (i = 0; i < TPS6507X_NUM_REGULATOR; i++) regulator_unregister(tps->rdev[i]); @@ -582,59 +622,13 @@ static int __devexit tps6507x_pmic_remove(struct i2c_client *client) return 0; } -static const struct tps_info tps6507x_pmic_regs[] = { - { - .name = "VDCDC1", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "VDCDC2", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "VDCDC3", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(VDCDCx_VSEL_table), - .table = VDCDCx_VSEL_table, - }, - { - .name = "LDO1", - .min_uV = 1000000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(LDO1_VSEL_table), - .table = LDO1_VSEL_table, - }, - { - .name = "LDO2", - .min_uV = 725000, - .max_uV = 3300000, - .table_len = ARRAY_SIZE(LDO2_VSEL_table), - .table = LDO2_VSEL_table, - }, -}; - -static const struct i2c_device_id tps6507x_pmic_id[] = { - {.name = "tps6507x", - .driver_data = (unsigned long) tps6507x_pmic_regs,}, - { }, -}; -MODULE_DEVICE_TABLE(i2c, tps6507x_pmic_id); - -static struct i2c_driver tps6507x_i2c_driver = { +static struct platform_driver tps6507x_pmic_driver = { .driver = { - .name = "tps6507x", + .name = "tps6507x-pmic", .owner = THIS_MODULE, }, .probe = tps6507x_pmic_probe, .remove = __devexit_p(tps6507x_pmic_remove), - .id_table = tps6507x_pmic_id, }; /** @@ -644,7 +638,7 @@ static struct i2c_driver tps6507x_i2c_driver = { */ static int __init tps6507x_pmic_init(void) { - return i2c_add_driver(&tps6507x_i2c_driver); + return platform_driver_register(&tps6507x_pmic_driver); } subsys_initcall(tps6507x_pmic_init); @@ -655,10 +649,11 @@ subsys_initcall(tps6507x_pmic_init); */ static void __exit tps6507x_pmic_cleanup(void) { - i2c_del_driver(&tps6507x_i2c_driver); + platform_driver_unregister(&tps6507x_pmic_driver); } module_exit(tps6507x_pmic_cleanup); MODULE_AUTHOR("Texas Instruments"); MODULE_DESCRIPTION("TPS6507x voltage regulator driver"); MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps6507x-pmic"); diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index fd73af5..9543cb7 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -131,6 +131,8 @@ /* VDCDC MASK */ #define TPS6507X_DEFDCDCX_DCDC_MASK 0X3F +#define TPS6507X_MAX_REGISTER 0X19 + /** * struct tps6507x_board - packages regulator and touchscreen init data * @tps6507x_regulator_data: regulator initialization values @@ -142,4 +144,24 @@ struct tps6507x_board { struct regulator_init_data *tps6507x_pmic_init_data; }; +/** + * struct tps6507x_dev - tps6507x sub-driver chip access routines + * @read_dev() - I2C register read function + * @write_dev() - I2C register write function + * + * Device data may be used to access the TPS6507x chip + */ + +struct tps6507x_dev { + struct device *dev; + struct i2c_client *i2c_client; + int (*read_dev)(struct tps6507x_dev *tps6507x, char reg, int size, + void *dest); + int (*write_dev)(struct tps6507x_dev *tps6507x, char reg, int size, + void *src); + + /* Client devices */ + struct tps6507x_pmic *pmic; +}; + #endif /* __LINUX_MFD_TPS6507X_H */ -- 1.6.0.4 From todd.fischer at ridgerun.com Sat Apr 3 17:16:40 2010 From: todd.fischer at ridgerun.com (Todd Fischer) Date: Sat, 3 Apr 2010 17:16:40 -0600 Subject: [PATCH] Add touch screen input driver for TPS6507x family of multi-function chips. Message-ID: <1270336600-1664-1-git-send-email-todd.fischer@ridgerun.com> The TPS6507x family of Texas Instruments power management ICs (pmic) are multi-function chips that include voltage regulation and touch screen controller capabilities. This patch adds a touch screen input driver for the TPS6507x pmic. There was an existing regulator driver. Before the touch screen driver could be added, a multi-function device (MFD) driver was needed and the regulator driver modified to use the MDF driver. Patches for these changes have been posted and reviewed. The TPS6507x touch screen driver applies cleanly to the MFD GIT repo after the above referenced patches are applied. If I should use a different approach for the touch screen driver, please let me know. Signed-off-by: Todd Fischer --- arch/arm/mach-davinci/board-da850-evm.c | 12 + drivers/input/touchscreen/Kconfig | 13 + drivers/input/touchscreen/Makefile | 1 + drivers/input/touchscreen/tps6507x-ts.c | 400 +++++++++++++++++++++++++++++++ drivers/mfd/tps6507x.c | 3 + include/linux/input/tps6507x-ts.h | 24 ++ include/linux/mfd/tps6507x.h | 2 + 7 files changed, 455 insertions(+), 0 deletions(-) create mode 100644 drivers/input/touchscreen/tps6507x-ts.c create mode 100644 include/linux/input/tps6507x-ts.h diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c index d059924..b3cbb32 100644 --- a/arch/arm/mach-davinci/board-da850-evm.c +++ b/arch/arm/mach-davinci/board-da850-evm.c @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include #include @@ -534,8 +536,18 @@ struct regulator_init_data tps65070_regulator_data[] = { }, }; +static struct touchscreen_init_data tps6507x_touchscreen_data = { + .poll_period = 30, /* ms between touch samples */ + .min_pressure = 0x30, /* minimum pressure to trigger touch */ + .vref = 0, /* turn off vref when not using A/D */ + .vendor = 0, /* /sys/class/input/input?/id/vendor */ + .product = 65070, /* /sys/class/input/input?/id/product */ + .version = 0x100, /* /sys/class/input/input?/id/version */ +}; + static struct tps6507x_board tps_board = { .tps6507x_pmic_init_data = &tps65070_regulator_data[0], + .tps6507x_ts_init_data = &tps6507x_touchscreen_data, }; static struct i2c_board_info __initdata da850evm_tps65070_info[] = { diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 8a8fa4d..6166aa8 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -594,4 +594,17 @@ config TOUCHSCREEN_PCAP To compile this driver as a module, choose M here: the module will be called pcap_ts. + +config TOUCHSCREEN_TPS6507X + tristate "TPS6507x based touchscreens" + depends on I2C + help + Say Y here if you have a TPS6507x based touchscreen + controller. + + If unsure, say N. + + To compile this driver as a module, choose M here: the + module will be called tps6507x_ts. + endif diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 7fef7d5..cfa83d0 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -46,3 +46,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o +obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c new file mode 100644 index 0000000..5de80a1 --- /dev/null +++ b/drivers/input/touchscreen/tps6507x-ts.c @@ -0,0 +1,400 @@ +/* + * drivers/input/touchscreen/tps6507x_ts.c + * + * Touchscreen driver for the tps6507x chip. + * + * Copyright (c) 2009 RidgeRun (todd.fischer at ridgerun.com) + * + * Credits: + * + * Using code from tsc2007, MtekVision Co., Ltd. + * + * For licencing details see kernel-base/COPYING + * + * TPS65070, TPS65073, TPS650731, and TPS650732 support + * 10 bit touch screen interface. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#define TSC_DEFAULT_POLL_PERIOD 30 /* ms */ +#define TPS_DEFAULT_MIN_PRESSURE 0x30 +#define MAX_10BIT ((1 << 10) - 1) + +#define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \ + TPS6507X_ADCONFIG_START_CONVERSION | \ + TPS6507X_ADCONFIG_INPUT_REAL_TSC) +#define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC) + +struct ts_event { + u16 x; + u16 y; + u16 pressure; +}; + +struct tps6507x_ts { + struct input_dev *input_dev; + struct device *dev; + char phys[32]; + struct workqueue_struct *wq; + struct delayed_work work; + unsigned polling; /* polling is active */ + struct ts_event tc; + struct tps6507x_dev *mfd; + u16 model; + unsigned pendown; + int irq; + void (*clear_penirq)(void); + unsigned long poll_period; /* ms */ + u16 min_pressure; + int vref; /* non-zero to leave vref on */ +}; + +static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) +{ + int err; + + err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data); + + if (err) + return err; + + return 0; +} + +static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data) +{ + return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data); +} + +static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc, + u8 tsc_mode, u16 *value) +{ + s32 ret; + u8 adc_status; + u8 result; + + /* Route input signal to A/D converter */ + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode); + if (ret) { + dev_err(tsc->dev, "TSC mode read failed\n"); + goto err; + } + + /* Start A/D conversion */ + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, + TPS6507X_ADCONFIG_CONVERT_TS); + if (ret) { + dev_err(tsc->dev, "ADC config write failed\n"); + return ret; + } + + do { + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG, + &adc_status); + if (ret) { + dev_err(tsc->dev, "ADC config read failed\n"); + goto err; + } + } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION); + + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result); + if (ret) { + dev_err(tsc->dev, "ADC result 2 read failed\n"); + goto err; + } + + *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8; + + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result); + if (ret) { + dev_err(tsc->dev, "ADC result 1 read failed\n"); + goto err; + } + + *value |= result; + + dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value); + +err: + return ret; +} + +/* Need to call tps6507x_adc_standby() after using A/D converter for the + * touch screen interrupt to work properly. + */ + +static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) +{ + s32 ret; + s32 loops = 0; + u8 val; + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, + TPS6507X_ADCONFIG_INPUT_TSC); + if (ret) + return ret; + + ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, + TPS6507X_TSCMODE_STANDBY); + if (ret) + return ret; + + ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); + if (ret) + return ret; + + while (val & TPS6507X_REG_TSC_INT) { + mdelay(10); + ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); + if (ret) + return ret; + loops++; + } + + return ret; +} + +static void tps6507x_ts_handler(struct work_struct *work) +{ + struct tps6507x_ts *tsc = container_of(work, + struct tps6507x_ts, work.work); + struct input_dev *input_dev = tsc->input_dev; + int pendown; + int schd; + int poll = 0; + s32 ret; + + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, + &tsc->tc.pressure); + if (ret) + goto done; + + pendown = tsc->tc.pressure > tsc->min_pressure; + + if (unlikely(!pendown && tsc->pendown)) { + dev_dbg(tsc->dev, "UP\n"); + input_report_key(input_dev, BTN_TOUCH, 0); + input_report_abs(input_dev, ABS_PRESSURE, 0); + input_sync(input_dev); + tsc->pendown = 0; + } + + if (pendown) { + + if (!tsc->pendown) { + dev_dbg(tsc->dev, "DOWN\n"); + input_report_key(input_dev, BTN_TOUCH, 1); + } else + dev_dbg(tsc->dev, "still down\n"); + + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION, + &tsc->tc.x); + if (ret) + goto done; + + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION, + &tsc->tc.y); + if (ret) + goto done; + + input_report_abs(input_dev, ABS_X, tsc->tc.x); + input_report_abs(input_dev, ABS_Y, tsc->tc.y); + input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); + input_sync(input_dev); + tsc->pendown = 1; + poll = 1; + } + +done: + /* always poll if not using interrupts */ + poll = 1; + + if (poll) { + schd = queue_delayed_work(tsc->wq, &tsc->work, + tsc->poll_period * HZ / 1000); + if (schd) + tsc->polling = 1; + else { + tsc->polling = 0; + dev_err(tsc->dev, "re-schedule failed"); + } + } else + tsc->polling = 0; + + ret = tps6507x_adc_standby(tsc); +} + +static int tps6507x_ts_probe(struct platform_device *pdev) +{ + int error; + struct tps6507x_ts *tsc; + struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); + struct touchscreen_init_data *init_data; + struct input_dev *input_dev; + struct tps6507x_board *tps_board; + int schd; + + /** + * tps_board points to pmic related constants + * coming from the board-evm file. + */ + + tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; + + if (!tps_board) { + dev_err(tps6507x_dev->dev, + "Could not find tps6507x platform data\n"); + return -EIO; + } + + /** + * init_data points to array of regulator_init structures + * coming from the board-evm file. + */ + + init_data = tps_board->tps6507x_ts_init_data; + + tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); + if (!tsc) { + dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); + error = -ENOMEM; + goto err0; + } + + tps6507x_dev->ts = tsc; + tsc->mfd = tps6507x_dev; + tsc->dev = tps6507x_dev->dev; + input_dev = input_allocate_device(); + if (!input_dev) { + dev_err(tsc->dev, "Failed to allocate input device.\n"); + error = -ENOMEM; + goto err1; + } + + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); + + input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0); + input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0); + input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); + + input_dev->name = "TPS6507x Touchscreen"; + input_dev->id.bustype = BUS_I2C; + input_dev->dev.parent = tsc->dev; + + snprintf(tsc->phys, sizeof(tsc->phys), + "%s/input0", dev_name(tsc->dev)); + input_dev->phys = tsc->phys; + + dev_dbg(tsc->dev, "device: %s\n", input_dev->phys); + + input_set_drvdata(input_dev, tsc); + + tsc->input_dev = input_dev; + + INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); + tsc->wq = create_workqueue("TPS6507x Touchscreen"); + + if (init_data) { + tsc->poll_period = init_data->poll_period; + tsc->vref = init_data->vref; + tsc->min_pressure = init_data->min_pressure; + input_dev->id.vendor = init_data->vendor; + input_dev->id.product = init_data->product; + input_dev->id.version = init_data->version; + } else { + tsc->poll_period = TSC_DEFAULT_POLL_PERIOD; + tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE; + } + + error = tps6507x_adc_standby(tsc); + if (error) + goto err2; + + error = input_register_device(input_dev); + if (error) + goto err2; + + schd = queue_delayed_work(tsc->wq, &tsc->work, + tsc->poll_period * HZ / 1000); + + if (schd) + tsc->polling = 1; + else { + tsc->polling = 0; + dev_err(tsc->dev, "schedule failed"); + goto err2; + } + + return 0; + +err2: + cancel_delayed_work(&tsc->work); + flush_workqueue(tsc->wq); + destroy_workqueue(tsc->wq); + tsc->wq = 0; + input_free_device(input_dev); +err1: + kfree(tsc); + tps6507x_dev->ts = NULL; +err0: + return error; +} + +static int __devexit tps6507x_ts_remove(struct platform_device *pdev) +{ + struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); + struct tps6507x_ts *tsc = tps6507x_dev->ts; + struct input_dev *input_dev = tsc->input_dev; + + if (!tsc) + return 0; + + cancel_delayed_work(&tsc->work); + flush_workqueue(tsc->wq); + destroy_workqueue(tsc->wq); + tsc->wq = 0; + + input_free_device(input_dev); + + tps6507x_dev->ts = NULL; + kfree(tsc); + + return 0; +} + +static struct platform_driver tps6507x_ts_driver = { + .driver = { + .name = "tps6507x-ts", + .owner = THIS_MODULE, + }, + .probe = tps6507x_ts_probe, + .remove = __devexit_p(tps6507x_ts_remove), +}; + +static int __init tps6507x_ts_init(void) +{ + return platform_driver_register(&tps6507x_ts_driver); +} +module_init(tps6507x_ts_init); + +static void __exit tps6507x_ts_exit(void) +{ + platform_driver_unregister(&tps6507x_ts_driver); +} +module_exit(tps6507x_ts_exit); + +MODULE_AUTHOR("Todd Fischer "); +MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:tps6507x-tsc"); diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c index edda9ff..d05c52d 100644 --- a/drivers/mfd/tps6507x.c +++ b/drivers/mfd/tps6507x.c @@ -25,6 +25,9 @@ static struct mfd_cell tps6507x_devs[] = { { .name = "tps6507x-pmic", }, + { + .name = "tps6507x-ts", + }, }; diff --git a/include/linux/input/tps6507x-ts.h b/include/linux/input/tps6507x-ts.h new file mode 100644 index 0000000..ab14403 --- /dev/null +++ b/include/linux/input/tps6507x-ts.h @@ -0,0 +1,24 @@ +/* linux/i2c/tps6507x-ts.h + * + * Functions to access TPS65070 touch screen chip. + * + * Copyright (c) 2009 RidgeRun (todd.fischer at ridgerun.com) + * + * + * For licencing details see kernel-base/COPYING + */ + +#ifndef __LINUX_I2C_TPS6507X_TS_H +#define __LINUX_I2C_TPS6507X_TS_H + +/* Board specific touch screen initial values */ +struct touchscreen_init_data { + int poll_period; /* ms */ + int vref; /* non-zero to leave vref on */ + __u16 min_pressure; /* min reading to be treated as a touch */ + __u16 vendor; + __u16 product; + __u16 version; +}; + +#endif /* __LINUX_I2C_TPS6507X_TS_H */ diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h index 9543cb7..c923e48 100644 --- a/include/linux/mfd/tps6507x.h +++ b/include/linux/mfd/tps6507x.h @@ -142,6 +142,7 @@ struct tps6507x_board { struct regulator_init_data *tps6507x_pmic_init_data; + struct touchscreen_init_data *tps6507x_ts_init_data; }; /** @@ -162,6 +163,7 @@ struct tps6507x_dev { /* Client devices */ struct tps6507x_pmic *pmic; + struct tps6507x_ts *ts; }; #endif /* __LINUX_MFD_TPS6507X_H */ -- 1.6.0.4 From martin at ti.com Sun Apr 4 11:49:49 2010 From: martin at ti.com (Ambrose, Martin) Date: Sun, 4 Apr 2010 11:49:49 -0500 Subject: [PATCH v2] DA8XX/OMAP-L1XX: FB: Implement double buffering In-Reply-To: References: <1269868554-17045-1-git-send-email-martin@ti.com> <20100330133621.e897cdb5.akpm@linux-foundation.org> Message-ID: On Wed, Mar 31, 2010 at 20:43:29, Ambrose, Martin wrote: > Andrew, > > Thanks for the feedback. > > > > +/* > > > + * Function to wait for vertical sync which for this LCD peripheral > > > + * translates into waiting for the current raster frame to complete. > > > + */ > > > +static int fb_wait_for_vsync(struct fb_info *info) > > > +{ > > > + struct da8xx_fb_par *par = info->par; > > > + wait_queue_t wq; > > > + int ret; > > > + > > > + init_waitqueue_entry(&wq, current); > > > > DECLARE_WAITQUEUE() would be more conventional. > > I'll update -- cloned this from some older code I think. After looking at this further this variable wasn't even used so I will trim this in upcoming v3 patch. Regards, Martin From martin at ti.com Sun Apr 4 11:51:16 2010 From: martin at ti.com (Ambrose, Martin) Date: Sun, 4 Apr 2010 11:51:16 -0500 Subject: [PATCH v2] DA8XX/OMAP-L1XX: FB: Implement double buffering In-Reply-To: <70E876B0EA86DD4BAF101844BC814DFE0FDD0EFE@Cloud.RL.local> References: <20100331203256.852450d3.akpm@linux-foundation.org> <70E876B0EA86DD4BAF101844BC814DFE0FDD0EFE@Cloud.RL.local> Message-ID: On Thu, Apr 01, 2010 at 01:47:40, Jon Povey wrote: > Andrew Morton wrote: > > On Wed, 31 Mar 2010 20:43:29 -0500 "Ambrose, Martin" > > wrote: > > >>> If the calling process has signal_pending() (say, someone hit ^C) > >>> then wait_event_interruptible_timeout() will fall straight through > >>> with -ERESTARTSYS. Will this cause the driver to malfunction at > >>> all? > >> > >> I don't think so since the driver doesn't make use of this > >> information in any way. This is just status to the caller that the > >> current frame has finished DMA'ing out of the framebuffer. > >> > >> Could you maybe propose a scenario/use case where you think it is > >> problematic? I could then either reason why it should be OK or > >> I'll create a test harness and see how the driver can/should be > >> modified. > > > > Gee, I dunno - I don't understand the driver to that level. If you're > > OK with this wait being interrupted by a signal and the driver handles > > it OK then fine, that's a feature. > > > > To test it I suppose you should give your test app a signal handler > > and blast kills at it from another process. > > Jumping in.. > > This should not cause a problem for the driver; its purpose is to tell userland that it can > write to the buffer without corrupting graphics (as presumably it is double-buffering and > the other buffer is now being DMA'd from by the hardware). > > At worst, if the userland software doesn't handle this correctly it may draw one bad frame of graphics. Although if it's had a ctrl-C it probably has bigger things to worry about. > > If the app wants to handle signals it needs to consider such things.. I would not expect the driver to do anything other than what this patch does. Thanks Jon. I agree. If no further objections I'll leave this as is. Regards, Martin From nsekhar at ti.com Mon Apr 5 01:18:20 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 11:48:20 +0530 Subject: [PATCH v2 09/16] Davinci: tnetv107x SOC specific header In-Reply-To: <1269553439-14886-10-git-send-email-cyril@ti.com> References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> Message-ID: On Fri, Mar 26, 2010 at 03:13:52, Chemparathy, Cyril wrote: > Added on-chip peripheral base addresses so tnetv107x SOC header. > There should be no need to define the full list of base addresses in one place because the are typically needed only at only one place (near the resource definition). Just add the define where needed and use it. Thanks, Sekhar From nsekhar at ti.com Mon Apr 5 01:27:52 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 11:57:52 +0530 Subject: [PATCH v2 11/16] Davinci: tnetv107x edma definitions In-Reply-To: <1269553439-14886-12-git-send-email-cyril@ti.com> References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> <1269553439-14886-11-git-send-email-cyril@ti.com> <1269553439-14886-12-git-send-email-cyril@ti.com> Message-ID: Hi Cyril, On Fri, Mar 26, 2010 at 03:13:54, Chemparathy, Cyril wrote: > Added edma definitions for the tnetv107x soc. > > Signed-off-by: Cyril Chemparathy > --- > arch/arm/mach-davinci/include/mach/edma.h | 53 +++++++++++++++++++++++++++++ > 1 files changed, 53 insertions(+), 0 deletions(-) > > diff --git a/arch/arm/mach-davinci/include/mach/edma.h b/arch/arm/mach-davinci/include/mach/edma.h > index ced3092..e9d9fd2 100644 > --- a/arch/arm/mach-davinci/include/mach/edma.h > +++ b/arch/arm/mach-davinci/include/mach/edma.h > @@ -187,6 +187,59 @@ enum DA830_edma_ch { > DA830_DMACH_UART2_TX > }; > > +/* TNETV107X specific EDMA3 information */ > +#define EDMA_TNETV107X_NUM_DMACH 64 > +#define EDMA_TNETV107X_NUM_TCC 64 > +#define EDMA_TNETV107X_NUM_PARAMENTRY 128 > +#define EDMA_TNETV107X_NUM_EVQUE 2 > +#define EDMA_TNETV107X_NUM_TC 2 > +#define EDMA_TNETV107X_CHMAP_EXIST 0 > +#define EDMA_TNETV107X_NUM_REGIONS 4 > +#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u > +#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu > + > +/* TNETV107X specific EDMA3 Events Information */ > +enum tnetv107x_edma_ch { > + TNETV107X_DMACH_AES_DMAREQIN = 3, > + TNETV107X_DMACH_AES_DMAREQOUT = 4, > + TNETV107X_DMACH_DES_DMAREQIN = 5, > + TNETV107X_DMACH_DES_DMAREQOUT = 6, > + TNETV107X_DMACH_SHA = 7, > + TNETV107X_DMACH_IMCOP_IMX = 8, > + TNETV107X_DMACH_IMCOP_VLCD = 9, > + TNETV107X_DMACH_IMCOP_SQR_ARM = 10, > + TNETV107X_DMACH_IMCOP_SQR_DSP = 11, > + TNETV107X_DMACH_PKA = 13, > + TNETV107X_DMACH_MDIO = 14, > + TNETV107X_DMACH_SSP = 15, > + TNETV107X_DMACH_UART1_RX = 18, > + TNETV107X_DMACH_UART1_TX = 19, > + TNETV107X_DMACH_SDIO0_RX = 26, > + TNETV107X_DMACH_SDIO0_TX = 27, > + TNETV107X_DMACH_SDIO1_RX = 28, > + TNETV107X_DMACH_SDIO1_TX = 29, > + TNETV107X_DMACH_GPIO00 = 32, > + TNETV107X_DMACH_GPIO01 = 33, > + TNETV107X_DMACH_GPIO02 = 34, > + TNETV107X_DMACH_GPIO03 = 35, > + TNETV107X_DMACH_EXT0 = 44, > + TNETV107X_DMACH_EXT1 = 45, > + TNETV107X_DMACH_GPIO12 = 46, > + TNETV107X_DMACH_GPIO13 = 47, > + TNETV107X_DMACH_TIMER00 = 48, > + TNETV107X_DMACH_TIMER01 = 49, > + TNETV107X_DMACH_TIMER10 = 50, > + TNETV107X_DMACH_TIMER11 = 51, > + TNETV107X_DMACH_TDM0_RXDMA = 52, > + TNETV107X_DMACH_TDM0_RXMCSP = 53, > + TNETV107X_DMACH_TDM0_TXDMA = 54, > + TNETV107X_DMACH_TDM0_TXMCSP = 55, > + TNETV107X_DMACH_TDM1_RXDMA = 56, > + TNETV107X_DMACH_TDM1_RXMCSP = 57, > + TNETV107X_DMACH_TDM1_TXDMA = 58, > + TNETV107X_DMACH_TDM1_TXMCSP = 59, > +}; If I am not forgetting, even DMA channel assignments are needed only where the IO resources are defined. So, no need for a definition in a header file. Readability will be improved if these are defined where actually used. I know this is coming from existing defines of this sort in edma.h, but, I don't think that's ideal. Thanks, Sekhar From nsekhar at ti.com Mon Apr 5 04:14:59 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 14:44:59 +0530 Subject: [PATCH v2 14/16] Davinci: tnetv107x gpio implementation In-Reply-To: <1269553439-14886-15-git-send-email-cyril@ti.com> References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> <1269553439-14886-11-git-send-email-cyril@ti.com> <1269553439-14886-12-git-send-email-cyril@ti.com> <1269553439-14886-13-git-send-email-cyril@ti.com> <1269553439-14886-14-git-send-email-cyril@ti.com> <1269553439-14886-15-git-send-email-cyril@ti.com> Message-ID: Hi Cyril, On Fri, Mar 26, 2010 at 03:13:57, Chemparathy, Cyril wrote: > Support for tnetv107x gpio controller. Note that this controller does not use > the gpio related definitions from davinci_soc_info. ... because this code is used only on one chip right now? How about when more devices of the same family are added? > > Further, this patch modifies davinci's inlined gpio functions to range check > against davinci_soc_info contents instead of DAVINCI_N_GPIO. This way, > tnetv107x systems can define davinci_soc_info.gpio_num to 0 and bypass the > inline routines. Why? Tnetv107x would benefit from inline GPIO functions as well. So, why not define separate inline functions for that chip? > > Signed-off-by: Cyril Chemparathy > --- > arch/arm/mach-davinci/Makefile | 1 + > arch/arm/mach-davinci/gpio-tnetv107x.c | 155 ++++++++++++++++++++++++ > arch/arm/mach-davinci/include/mach/gpio.h | 6 +- > arch/arm/mach-davinci/include/mach/tnetv107x.h | 4 + > 4 files changed, 163 insertions(+), 3 deletions(-) > create mode 100644 arch/arm/mach-davinci/gpio-tnetv107x.c > > diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile > index 6aac880..0284a4c 100644 > --- a/arch/arm/mach-davinci/Makefile > +++ b/arch/arm/mach-davinci/Makefile > @@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o devices.o > obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o > obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o > obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o > +obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o Err, you are building in support for both DaVinci and tnetv107x gpios. I thought the DaVinci GPIO code is not applicable for this chip. > > obj-$(CONFIG_AINTC) += irq.o > obj-$(CONFIG_CP_INTC) += cp_intc.o > diff --git a/arch/arm/mach-davinci/gpio-tnetv107x.c b/arch/arm/mach-davinci/gpio-tnetv107x.c > new file mode 100644 > index 0000000..d868b46 > --- /dev/null > +++ b/arch/arm/mach-davinci/gpio-tnetv107x.c > @@ -0,0 +1,155 @@ > +/* > + * TI TNETV107X GPIO Support > + * > + * Author: Cyril Chemparathy > + * > + * 2009 (c) Texas Instruments, Inc. This file is licensed under > + * the terms of the GNU General Public License version 2. This program > + * is licensed "as is" without any warranty of any kind, whether express > + * or implied. > + */ > +#include > +#include > +#include > + > +#include > +#include > + > +struct tnetv107x_gpio_regs { > + u32 idver; > + u32 data_in[3]; > + u32 data_out[3]; > + u32 direction[3]; > + u32 enable[3]; > +}; > + > +struct tnetv107x_gpio_controller { > + struct tnetv107x_gpio_regs __iomem *regs; > + struct gpio_chip chip; > +}; > + > +static struct tnetv107x_gpio_controller tnetv107x_gpio_controller; > + > +#define gpio_reg_index(gpio) ((gpio) >> 5) > +#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f) > + > +#define gpio_reg_rmw(reg, mask, val) \ > + __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg)) > + > +#define gpio_reg_set_bit(reg, gpio) \ > + gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio)) > + > +#define gpio_reg_clear_bit(reg, gpio) \ > + gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0) > + > +#define gpio_reg_get_bit(reg, gpio) \ > + (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio)) > + > +#define chip_to_gpio(chip) \ > + container_of(chip, struct tnetv107x_gpio_controller, chip) > + > +static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned gpio) > +{ > + struct tnetv107x_gpio_controller *ctlr = chip_to_gpio(chip); > + unsigned long flags; > + > + local_irq_save(flags); Should use spin_lock() for protection. > + > + gpio_reg_set_bit(&ctlr->regs->enable, gpio); > + > + local_irq_restore(flags); > + > + return 0; > +} > + [...] > +void __init tnetv107x_gpio_init(void) > +{ > + struct tnetv107x_gpio_controller *ctlr = &tnetv107x_gpio_controller; > + > + ctlr->regs = ioremap(TNETV107X_GPIO_BASE, PAGE_SIZE); > + > + ctlr->chip.label = "TNETV107X"; > + ctlr->chip.request = tnetv107x_gpio_request; > + ctlr->chip.free = tnetv107x_gpio_free; > + ctlr->chip.direction_input = tnetv107x_gpio_dir_in; > + ctlr->chip.get = tnetv107x_gpio_get; > + ctlr->chip.direction_output = tnetv107x_gpio_dir_out; > + ctlr->chip.set = tnetv107x_gpio_set; > + ctlr->chip.base = 0; > + ctlr->chip.ngpio = TNETV107X_N_GPIOS; > + ctlr->chip.can_sleep = 0; > + > + gpiochip_add(&ctlr->chip); > +} Why make it a global? Why not an initcall like the regular DaVinci gpio driver does? Thanks, Sekhar From nsekhar at ti.com Mon Apr 5 04:24:42 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 14:54:42 +0530 Subject: [PATCH v2 13/16] Davinci: simplified debug macros In-Reply-To: <1269553439-14886-14-git-send-email-cyril@ti.com> References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> <1269553439-14886-11-git-send-email-cyril@ti.com> <1269553439-14886-12-git-send-email-cyril@ti.com> <1269553439-14886-13-git-send-email-cyril@ti.com> <1269553439-14886-14-git-send-email-cyril@ti.com> Message-ID: Hi Cyril, On Fri, Mar 26, 2010 at 03:13:56, Chemparathy, Cyril wrote: > Simplified UART base address calculation for low-level debug macros. This > makes it much easier to add in support for other SOCs. > > Signed-off-by: Cyril Chemparathy > --- > arch/arm/mach-davinci/include/mach/debug-macro.S | 28 +++++++++++++-------- > arch/arm/mach-davinci/include/mach/hardware.h | 4 ++- > arch/arm/mach-davinci/include/mach/serial.h | 2 + > 3 files changed, 22 insertions(+), 12 deletions(-) > > diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S b/arch/arm/mach-davinci/include/mach/debug-macro.S > index 3cd93a8..b8b47a4 100644 > --- a/arch/arm/mach-davinci/include/mach/debug-macro.S > +++ b/arch/arm/mach-davinci/include/mach/debug-macro.S > @@ -17,22 +17,28 @@ > */ > > #include > +#include > + > +#if defined(CONFIG_ARCH_DAVINCI_DMx) > +#define UART_PHYS DAVINCI_UART0_BASE > +#define UART_VIRT IO_ADDRESS(UART_PHYS) > +#endif > + > +#if defined(CONFIG_ARCH_DAVINCI_DA8XX) > +#ifdef UART_PHYS > +#error "CONFIG_DEBUG_LL is incompatible with multiple archs" > +#endif > +#define UART_PHYS DA8XX_UART2_BASE > +#define UART_VIRT IO_ADDRESS(UART_PHYS) > +#endif > + > #define UART_SHIFT 2 > > .macro addruart, rx, tmp > mrc p15, 0, \rx, c1, c0 > tst \rx, #1 @ MMU enabled? > - moveq \rx, #0x01000000 @ physical base address > - movne \rx, #0xfe000000 @ virtual base > -#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && defined(CONFIG_ARCH_DAVINCI_DMx) > -#error Cannot enable DaVinci and DA8XX platforms concurrently > -#elif defined(CONFIG_MACH_DAVINCI_DA830_EVM) || \ > - defined(CONFIG_MACH_DAVINCI_DA850_EVM) > - orr \rx, \rx, #0x00d00000 @ physical base address > - orr \rx, \rx, #0x0000d000 @ of UART 2 > -#else > - orr \rx, \rx, #0x00c20000 @ UART 0 > -#endif > + ldreq \rx, =UART_PHYS > + ldrne \rx, =UART_VIRT As Sergei pointed out, this is making the debug UART dependent on the architecture which would be an incorrect thing to do. IMHO, a better simplification would be to let the debug UART number on a board be defined by Kconfig entry for that board and the code here could compute the UART base using that number. Thanks, Sekhar From nsekhar at ti.com Mon Apr 5 05:56:54 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 16:26:54 +0530 Subject: [PATCH v2 16/16] Davinci: initial tnetv107x evm board support In-Reply-To: <1269553439-14886-17-git-send-email-cyril@ti.com> References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> <1269553439-14886-11-git-send-email-cyril@ti.com> <1269553439-14886-12-git-send-email-cyril@ti.com> <1269553439-14886-13-git-send-email-cyril@ti.com> <1269553439-14886-14-git-send-email-cyril@ti.com> <1269553439-14886-15-git-send-email-cyril@ti.com> <1269553439-14886-16-git-send-email-cyril@ti.com> <1269553439-14886-17-git-send-email-cyril@ti.com> Message-ID: On Fri, Mar 26, 2010 at 03:13:59, Chemparathy, Cyril wrote: > Added support for tnetv107x evaluation module. Its odd to see the EVM being added before SoC... > > Signed-off-by: Cyril Chemparathy > --- [...] > > endchoice > > +config MACH_TNETV107X > + bool "TI TNETV107X Reference Platform" > + default ARCH_DAVINCI_TNETV107X > + depends on ARCH_DAVINCI_TNETV107X ... because of symbols like these which are being used before being defined cause git-bisect to break (although this particular case would be quite harmless). > + help > + Say Y here to select the TI TNETV107X Evaluation Module. > + > config DAVINCI_MUX > bool "DAVINCI multiplexing support" > depends on ARCH_DAVINCI > diff --git a/arch/arm/mach-davinci/Makefile b/arch/arm/mach-davinci/Makefile > index 62c5116..eab4c0f 100644 > --- a/arch/arm/mach-davinci/Makefile > +++ b/arch/arm/mach-davinci/Makefile > @@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += board-dm646x-evm.o cdce949.o > obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o > obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o > obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o > +obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o > > # Power Management > obj-$(CONFIG_CPU_FREQ) += cpufreq.o > diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c b/arch/arm/mach-davinci/board-tnetv107x-evm.c > new file mode 100644 > index 0000000..a6bf49c > --- /dev/null > +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c [...] > +static __init void tnetv107x_evm_board_init(void) > +{ > + int status; > + > + davinci_cfg_reg_list(tnetv107x_sdio1_pins); > + davinci_cfg_reg_list(tnetv107x_uart1_pins); > + davinci_cfg_reg_list(tnetv107x_gpio_pins); > + > + tnetv107x_gpio_init(); > + tnetv107x_edma_init(); > + tnetv107x_serial_init(tnetv107x_serial_pdata); > + > + status = gpio_request(TNETV107X_EVM_MMC_WP_GPIO, "MMC WP\n"); > + if (status < 0) { > + printk(KERN_ERR "cannot open mmcsd write protect gpio %d\n", > + TNETV107X_EVM_MMC_WP_GPIO); > + tnetv107x_evm_mmc_config.get_ro = NULL; > + } else > + gpio_direction_input(TNETV107X_EVM_MMC_WP_GPIO); Use braces on else here.. > + > + status = gpio_request(TNETV107X_EVM_MMC_CD_GPIO, "MMC CD\n"); > + if (status < 0) { > + printk(KERN_ERR "cannot open mmcsd card detect gpio %d\n", > + TNETV107X_EVM_MMC_CD_GPIO); > + tnetv107x_evm_mmc_config.get_cd = NULL; > + } else > + gpio_direction_input(TNETV107X_EVM_MMC_CD_GPIO); ... and here. > + > + platform_add_devices(tnetv107x_evm_devices, > + ARRAY_SIZE(tnetv107x_evm_devices)); No need to mux the CD and WP pins as GPIO pins? Thanks, Sekhar From nsekhar at ti.com Mon Apr 5 06:24:47 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 16:54:47 +0530 Subject: DM6446 and DSA (Distributed Switch Architecture) In-Reply-To: References: Message-ID: Hi Andreas, On Fri, Apr 02, 2010 at 14:28:15, Andreas Auer wrote: > Steve Chen schrieb: > > On Wed, Mar 31, 2010 at 2:44 AM, Andreas Auer wrote: > >> Hello, > >> > >> I'm using a customized board similar to the EVM with a DM6446 cpu. The main > >> difference is that I'm using a Micrel KSZ8893M ethernet switch. The ethernet > >> switch has an I2C config interface and the standard mdio interface. > >> Therefore, I'm using the DSA driver subsystem and wrote a small chip driver > >> (I took the KSZ8893 driver for the Blackfin processor as reference). > >> Now, my problem is that the ethernet mac of the Davinci cpu is initialized > >> (probed) later then the DSA driver. And therefore the DSA driver cannot find > >> a valid netdevice. > >> Does anyone know how to change the initialization order of the devices?? > >> Changing the order of the register_device_driver function calls has > >> basically no influence on the init sequence. > >> > >> Thanks, > >> Andreas > > > > Hello, > > > > I encounter the same issue with DA830/OMAP-l137 EVM. Instead of > > probing PHY to get speed and duplexity, the driver just set the speed > > and duplexity based on platform data. May want to take a look at the > > OMAP-l137. > > Thanks for your answer. I got another solution. The davinci_emac driver > calls the init function very late because of > late_initcall(davinci_emac_init); > > I changed this line: > module_init(davinci_emac_init); This change was made so EMAC can get initialized after the SPI subsystem (so mac address could be fetched from SPI flash). Seems like there are one too many initialization order dependencies around EMAC driver. Is it possible to get your DSA driver to be a late_initcall too? Within the same initcall level the order is determined by the order In which the makefile lists the .o file. Thanks, Sekhar From nsekhar at ti.com Mon Apr 5 06:35:39 2010 From: nsekhar at ti.com (Nori, Sekhar) Date: Mon, 5 Apr 2010 17:05:39 +0530 Subject: [PATCH v2 16/16] Davinci: initial tnetv107x evm board support In-Reply-To: References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> <1269553439-14886-11-git-send-email-cyril@ti.com> <1269553439-14886-12-git-send-email-cyril@ti.com> <1269553439-14886-13-git-send-email-cyril@ti.com> <1269553439-14886-14-git-send-email-cyril@ti.com> <1269553439-14886-15-git-send-email-cyril@ti.com> <1269553439-14886-16-git-send-email-cyril@ti.com> <1269553439-14886-17-git-send-email-cyril@ti.com> Message-ID: On Mon, Apr 05, 2010 at 16:26:54, Nori, Sekhar wrote: > On Fri, Mar 26, 2010 at 03:13:59, Chemparathy, Cyril wrote: > > Added support for tnetv107x evaluation module. > > Its odd to see the EVM being added before SoC... > > > > > Signed-off-by: Cyril Chemparathy > > --- > > [...] > > > > > endchoice > > > > +config MACH_TNETV107X > > + bool "TI TNETV107X Reference Platform" > > + default ARCH_DAVINCI_TNETV107X > > + depends on ARCH_DAVINCI_TNETV107X > > ... because of symbols like these which are being used before > being defined cause git-bisect to break (although this particular > case would be quite harmless). Argh, please ignore this comment. Obviously I was seeing double. Thanks, Sekhar From uniquepiya at gmail.com Mon Apr 5 06:36:10 2010 From: uniquepiya at gmail.com (priyanka patny) Date: Mon, 5 Apr 2010 04:36:10 -0700 Subject: Davinci-linux-open-source Digest, Vol 52, Issue 9 In-Reply-To: References: Message-ID: how can i use opencv on davinci processor can anybody tell me please On 4/5/10, davinci-linux-open-source-request at linux.davincidsp.com < davinci-linux-open-source-request at linux.davincidsp.com> wrote: > > Send Davinci-linux-open-source mailing list submissions to > davinci-linux-open-source at linux.davincidsp.com > > To subscribe or unsubscribe via the World Wide Web, visit > > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > or, via email, send a message with subject or body 'help' to > davinci-linux-open-source-request at linux.davincidsp.com > > You can reach the person managing the list at > davinci-linux-open-source-owner at linux.davincidsp.com > > When replying, please edit your Subject line so it is more specific > than "Re: Contents of Davinci-linux-open-source digest..." > > > Today's Topics: > > 1. RE: [PATCH v2 09/16] Davinci: tnetv107x SOC specific header > (Nori, Sekhar) > 2. RE: [PATCH v2 11/16] Davinci: tnetv107x edma definitions > (Nori, Sekhar) > 3. RE: [PATCH v2 14/16] Davinci: tnetv107x gpio implementation > (Nori, Sekhar) > 4. RE: [PATCH v2 13/16] Davinci: simplified debug macros > (Nori, Sekhar) > 5. RE: [PATCH v2 16/16] Davinci: initial tnetv107x evm board > support (Nori, Sekhar) > 6. RE: DM6446 and DSA (Distributed Switch Architecture) > (Nori, Sekhar) > > > ---------------------------------------------------------------------- > > Message: 1 > Date: Mon, 5 Apr 2010 11:48:20 +0530 > From: "Nori, Sekhar" > To: "Chemparathy, Cyril" > Cc: "davinci-linux-open-source at linux.davincidsp.com" > , > "sshtylyov at mvista.com" > Subject: RE: [PATCH v2 09/16] Davinci: tnetv107x SOC specific header > Message-ID: > > Content-Type: text/plain; charset="iso-8859-1" > > On Fri, Mar 26, 2010 at 03:13:52, Chemparathy, Cyril wrote: > > Added on-chip peripheral base addresses so tnetv107x SOC header. > > > > There should be no need to define the full > list of base addresses in one place because > the are typically needed only at only one place > (near the resource definition). > > Just add the define where needed and use it. > > Thanks, > Sekhar > > > > ------------------------------ > > Message: 2 > Date: Mon, 5 Apr 2010 11:57:52 +0530 > From: "Nori, Sekhar" > To: "Chemparathy, Cyril" > Cc: "davinci-linux-open-source at linux.davincidsp.com" > , > "sshtylyov at mvista.com" > Subject: RE: [PATCH v2 11/16] Davinci: tnetv107x edma definitions > Message-ID: > > Content-Type: text/plain; charset="iso-8859-1" > > > Hi Cyril, > > On Fri, Mar 26, 2010 at 03:13:54, Chemparathy, Cyril wrote: > > Added edma definitions for the tnetv107x soc. > > > > Signed-off-by: Cyril Chemparathy > > --- > > arch/arm/mach-davinci/include/mach/edma.h | 53 > +++++++++++++++++++++++++++++ > > 1 files changed, 53 insertions(+), 0 deletions(-) > > > > diff --git a/arch/arm/mach-davinci/include/mach/edma.h > b/arch/arm/mach-davinci/include/mach/edma.h > > index ced3092..e9d9fd2 100644 > > --- a/arch/arm/mach-davinci/include/mach/edma.h > > +++ b/arch/arm/mach-davinci/include/mach/edma.h > > @@ -187,6 +187,59 @@ enum DA830_edma_ch { > > DA830_DMACH_UART2_TX > > }; > > > > +/* TNETV107X specific EDMA3 information */ > > +#define EDMA_TNETV107X_NUM_DMACH 64 > > +#define EDMA_TNETV107X_NUM_TCC 64 > > +#define EDMA_TNETV107X_NUM_PARAMENTRY 128 > > +#define EDMA_TNETV107X_NUM_EVQUE 2 > > +#define EDMA_TNETV107X_NUM_TC 2 > > +#define EDMA_TNETV107X_CHMAP_EXIST 0 > > +#define EDMA_TNETV107X_NUM_REGIONS 4 > > +#define TNETV107X_DMACH2EVENT_MAP0 0x3C0CE000u > > +#define TNETV107X_DMACH2EVENT_MAP1 0x000FFFFFu > > + > > +/* TNETV107X specific EDMA3 Events Information */ > > +enum tnetv107x_edma_ch { > > + TNETV107X_DMACH_AES_DMAREQIN = 3, > > + TNETV107X_DMACH_AES_DMAREQOUT = 4, > > + TNETV107X_DMACH_DES_DMAREQIN = 5, > > + TNETV107X_DMACH_DES_DMAREQOUT = 6, > > + TNETV107X_DMACH_SHA = 7, > > + TNETV107X_DMACH_IMCOP_IMX = 8, > > + TNETV107X_DMACH_IMCOP_VLCD = 9, > > + TNETV107X_DMACH_IMCOP_SQR_ARM = 10, > > + TNETV107X_DMACH_IMCOP_SQR_DSP = 11, > > + TNETV107X_DMACH_PKA = 13, > > + TNETV107X_DMACH_MDIO = 14, > > + TNETV107X_DMACH_SSP = 15, > > + TNETV107X_DMACH_UART1_RX = 18, > > + TNETV107X_DMACH_UART1_TX = 19, > > + TNETV107X_DMACH_SDIO0_RX = 26, > > + TNETV107X_DMACH_SDIO0_TX = 27, > > + TNETV107X_DMACH_SDIO1_RX = 28, > > + TNETV107X_DMACH_SDIO1_TX = 29, > > + TNETV107X_DMACH_GPIO00 = 32, > > + TNETV107X_DMACH_GPIO01 = 33, > > + TNETV107X_DMACH_GPIO02 = 34, > > + TNETV107X_DMACH_GPIO03 = 35, > > + TNETV107X_DMACH_EXT0 = 44, > > + TNETV107X_DMACH_EXT1 = 45, > > + TNETV107X_DMACH_GPIO12 = 46, > > + TNETV107X_DMACH_GPIO13 = 47, > > + TNETV107X_DMACH_TIMER00 = 48, > > + TNETV107X_DMACH_TIMER01 = 49, > > + TNETV107X_DMACH_TIMER10 = 50, > > + TNETV107X_DMACH_TIMER11 = 51, > > + TNETV107X_DMACH_TDM0_RXDMA = 52, > > + TNETV107X_DMACH_TDM0_RXMCSP = 53, > > + TNETV107X_DMACH_TDM0_TXDMA = 54, > > + TNETV107X_DMACH_TDM0_TXMCSP = 55, > > + TNETV107X_DMACH_TDM1_RXDMA = 56, > > + TNETV107X_DMACH_TDM1_RXMCSP = 57, > > + TNETV107X_DMACH_TDM1_TXDMA = 58, > > + TNETV107X_DMACH_TDM1_TXMCSP = 59, > > +}; > > If I am not forgetting, even DMA channel assignments > are needed only where the IO resources are defined. > So, no need for a definition in a header file. > > Readability will be improved if these are defined > where actually used. > > I know this is coming from existing defines of this > sort in edma.h, but, I don't think that's ideal. > > Thanks, > Sekhar > > > ------------------------------ > > Message: 3 > Date: Mon, 5 Apr 2010 14:44:59 +0530 > From: "Nori, Sekhar" > To: "Chemparathy, Cyril" > Cc: "davinci-linux-open-source at linux.davincidsp.com" > , > "sshtylyov at mvista.com" > Subject: RE: [PATCH v2 14/16] Davinci: tnetv107x gpio implementation > Message-ID: > > Content-Type: text/plain; charset="iso-8859-1" > > Hi Cyril, > > On Fri, Mar 26, 2010 at 03:13:57, Chemparathy, Cyril wrote: > > Support for tnetv107x gpio controller. Note that this controller does > not use > > the gpio related definitions from davinci_soc_info. > > ... because this code is used only on one chip right now? How about > when more devices of the same family are added? > > > > > Further, this patch modifies davinci's inlined gpio functions to range > check > > against davinci_soc_info contents instead of DAVINCI_N_GPIO. This way, > > tnetv107x systems can define davinci_soc_info.gpio_num to 0 and bypass > the > > inline routines. > > Why? Tnetv107x would benefit from inline GPIO functions as well. > So, why not define separate inline functions for that chip? > > > > > Signed-off-by: Cyril Chemparathy > > --- > > arch/arm/mach-davinci/Makefile | 1 + > > arch/arm/mach-davinci/gpio-tnetv107x.c | 155 > ++++++++++++++++++++++++ > > arch/arm/mach-davinci/include/mach/gpio.h | 6 +- > > arch/arm/mach-davinci/include/mach/tnetv107x.h | 4 + > > 4 files changed, 163 insertions(+), 3 deletions(-) > > create mode 100644 arch/arm/mach-davinci/gpio-tnetv107x.c > > > > diff --git a/arch/arm/mach-davinci/Makefile > b/arch/arm/mach-davinci/Makefile > > index 6aac880..0284a4c 100644 > > --- a/arch/arm/mach-davinci/Makefile > > +++ b/arch/arm/mach-davinci/Makefile > > @@ -16,6 +16,7 @@ obj-$(CONFIG_ARCH_DAVINCI_DM646x) += dm646x.o > devices.o > > obj-$(CONFIG_ARCH_DAVINCI_DM365) += dm365.o devices.o > > obj-$(CONFIG_ARCH_DAVINCI_DA830) += da830.o devices-da8xx.o > > obj-$(CONFIG_ARCH_DAVINCI_DA850) += da850.o devices-da8xx.o > > +obj-$(CONFIG_ARCH_DAVINCI_TNETV107X) += gpio-tnetv107x.o > > Err, you are building in support for both DaVinci and > tnetv107x gpios. I thought the DaVinci GPIO code is not > applicable for this chip. > > > > > obj-$(CONFIG_AINTC) += irq.o > > obj-$(CONFIG_CP_INTC) += cp_intc.o > > diff --git a/arch/arm/mach-davinci/gpio-tnetv107x.c > b/arch/arm/mach-davinci/gpio-tnetv107x.c > > new file mode 100644 > > index 0000000..d868b46 > > --- /dev/null > > +++ b/arch/arm/mach-davinci/gpio-tnetv107x.c > > @@ -0,0 +1,155 @@ > > +/* > > + * TI TNETV107X GPIO Support > > + * > > + * Author: Cyril Chemparathy > > + * > > + * 2009 (c) Texas Instruments, Inc. This file is licensed under > > + * the terms of the GNU General Public License version 2. This program > > + * is licensed "as is" without any warranty of any kind, whether express > > + * or implied. > > + */ > > +#include > > +#include > > +#include > > + > > +#include > > +#include > > + > > +struct tnetv107x_gpio_regs { > > + u32 idver; > > + u32 data_in[3]; > > + u32 data_out[3]; > > + u32 direction[3]; > > + u32 enable[3]; > > +}; > > + > > +struct tnetv107x_gpio_controller { > > + struct tnetv107x_gpio_regs __iomem *regs; > > + struct gpio_chip chip; > > +}; > > + > > +static struct tnetv107x_gpio_controller tnetv107x_gpio_controller; > > + > > +#define gpio_reg_index(gpio) ((gpio) >> 5) > > +#define gpio_reg_bit(gpio) BIT((gpio) & 0x1f) > > + > > +#define gpio_reg_rmw(reg, mask, val) \ > > + __raw_writel((__raw_readl(reg) & ~(mask)) | (val), (reg)) > > + > > +#define gpio_reg_set_bit(reg, gpio) \ > > + gpio_reg_rmw((reg) + gpio_reg_index(gpio), 0, gpio_reg_bit(gpio)) > > + > > +#define gpio_reg_clear_bit(reg, gpio) \ > > + gpio_reg_rmw((reg) + gpio_reg_index(gpio), gpio_reg_bit(gpio), 0) > > + > > +#define gpio_reg_get_bit(reg, gpio) \ > > + (__raw_readl((reg) + gpio_reg_index(gpio)) & gpio_reg_bit(gpio)) > > + > > +#define chip_to_gpio(chip) \ > > + container_of(chip, struct tnetv107x_gpio_controller, chip) > > + > > +static int tnetv107x_gpio_request(struct gpio_chip *chip, unsigned gpio) > > +{ > > + struct tnetv107x_gpio_controller *ctlr = chip_to_gpio(chip); > > + unsigned long flags; > > + > > + local_irq_save(flags); > > Should use spin_lock() for protection. > > > + > > + gpio_reg_set_bit(&ctlr->regs->enable, gpio); > > + > > + local_irq_restore(flags); > > + > > + return 0; > > +} > > + > > [...] > > > +void __init tnetv107x_gpio_init(void) > > +{ > > + struct tnetv107x_gpio_controller *ctlr = > &tnetv107x_gpio_controller; > > + > > + ctlr->regs = ioremap(TNETV107X_GPIO_BASE, PAGE_SIZE); > > + > > + ctlr->chip.label = "TNETV107X"; > > + ctlr->chip.request = tnetv107x_gpio_request; > > + ctlr->chip.free = tnetv107x_gpio_free; > > + ctlr->chip.direction_input = tnetv107x_gpio_dir_in; > > + ctlr->chip.get = tnetv107x_gpio_get; > > + ctlr->chip.direction_output = tnetv107x_gpio_dir_out; > > + ctlr->chip.set = tnetv107x_gpio_set; > > + ctlr->chip.base = 0; > > + ctlr->chip.ngpio = TNETV107X_N_GPIOS; > > + ctlr->chip.can_sleep = 0; > > + > > + gpiochip_add(&ctlr->chip); > > +} > > Why make it a global? Why not an initcall like the regular > DaVinci gpio driver does? > > Thanks, > Sekhar > > > > ------------------------------ > > Message: 4 > Date: Mon, 5 Apr 2010 14:54:42 +0530 > From: "Nori, Sekhar" > To: "Chemparathy, Cyril" > Cc: "davinci-linux-open-source at linux.davincidsp.com" > , > "sshtylyov at mvista.com" > Subject: RE: [PATCH v2 13/16] Davinci: simplified debug macros > Message-ID: > > Content-Type: text/plain; charset="iso-8859-1" > > > Hi Cyril, > > On Fri, Mar 26, 2010 at 03:13:56, Chemparathy, Cyril wrote: > > Simplified UART base address calculation for low-level debug > macros. This > > makes it much easier to add in support for other SOCs. > > > > Signed-off-by: Cyril Chemparathy > > --- > > arch/arm/mach-davinci/include/mach/debug-macro.S | 28 > +++++++++++++-------- > > arch/arm/mach-davinci/include/mach/hardware.h | 4 ++- > > arch/arm/mach-davinci/include/mach/serial.h | 2 + > > 3 files changed, 22 insertions(+), 12 deletions(-) > > > > diff --git a/arch/arm/mach-davinci/include/mach/debug-macro.S > b/arch/arm/mach-davinci/include/mach/debug-macro.S > > index 3cd93a8..b8b47a4 100644 > > --- a/arch/arm/mach-davinci/include/mach/debug-macro.S > > +++ b/arch/arm/mach-davinci/include/mach/debug-macro.S > > @@ -17,22 +17,28 @@ > > */ > > > > #include > > +#include > > + > > +#if defined(CONFIG_ARCH_DAVINCI_DMx) > > +#define UART_PHYS DAVINCI_UART0_BASE > > +#define UART_VIRT IO_ADDRESS(UART_PHYS) > > +#endif > > + > > +#if defined(CONFIG_ARCH_DAVINCI_DA8XX) > > +#ifdef UART_PHYS > > +#error "CONFIG_DEBUG_LL is incompatible with multiple archs" > > +#endif > > +#define UART_PHYS DA8XX_UART2_BASE > > +#define UART_VIRT IO_ADDRESS(UART_PHYS) > > +#endif > > + > > #define UART_SHIFT 2 > > > > .macro addruart, rx, tmp > > mrc p15, 0, \rx, c1, c0 > > tst \rx, #1 @ MMU enabled? > > - moveq \rx, #0x01000000 @ physical base address > > - movne \rx, #0xfe000000 @ virtual base > > -#if defined(CONFIG_ARCH_DAVINCI_DA8XX) && > defined(CONFIG_ARCH_DAVINCI_DMx) > > -#error Cannot enable DaVinci and DA8XX platforms concurrently > > -#elif defined(CONFIG_MACH_DAVINCI_DA830_EVM) || \ > > - defined(CONFIG_MACH_DAVINCI_DA850_EVM) > > - orr \rx, \rx, #0x00d00000 @ physical base address > > - orr \rx, \rx, #0x0000d000 @ of UART 2 > > -#else > > - orr \rx, \rx, #0x00c20000 @ UART 0 > > -#endif > > + ldreq \rx, =UART_PHYS > > + ldrne \rx, =UART_VIRT > > > As Sergei pointed out, this is making the debug > UART dependent on the architecture which would be > an incorrect thing to do. > > IMHO, a better simplification would be to let the debug > UART number on a board be defined by Kconfig entry for that > board and the code here could compute the UART base using > that number. > > Thanks, > Sekhar > > > > ------------------------------ > > Message: 5 > Date: Mon, 5 Apr 2010 16:26:54 +0530 > From: "Nori, Sekhar" > To: "Chemparathy, Cyril" > Cc: "davinci-linux-open-source at linux.davincidsp.com" > , > "sshtylyov at mvista.com" > Subject: RE: [PATCH v2 16/16] Davinci: initial tnetv107x evm board > support > Message-ID: > > Content-Type: text/plain; charset="iso-8859-1" > > On Fri, Mar 26, 2010 at 03:13:59, Chemparathy, Cyril wrote: > > Added support for tnetv107x evaluation module. > > Its odd to see the EVM being added before SoC... > > > > > Signed-off-by: Cyril Chemparathy > > --- > > [...] > > > > > endchoice > > > > +config MACH_TNETV107X > > + bool "TI TNETV107X Reference Platform" > > + default ARCH_DAVINCI_TNETV107X > > + depends on ARCH_DAVINCI_TNETV107X > > ... because of symbols like these which are being used before > being defined cause git-bisect to break (although this particular > case would be quite harmless). > > > + help > > + Say Y here to select the TI TNETV107X Evaluation Module. > > + > > config DAVINCI_MUX > > bool "DAVINCI multiplexing support" > > depends on ARCH_DAVINCI > > diff --git a/arch/arm/mach-davinci/Makefile > b/arch/arm/mach-davinci/Makefile > > index 62c5116..eab4c0f 100644 > > --- a/arch/arm/mach-davinci/Makefile > > +++ b/arch/arm/mach-davinci/Makefile > > @@ -32,6 +32,7 @@ obj-$(CONFIG_MACH_DAVINCI_DM6467_EVM) += > board-dm646x-evm.o cdce949.o > > obj-$(CONFIG_MACH_DAVINCI_DM365_EVM) += board-dm365-evm.o > > obj-$(CONFIG_MACH_DAVINCI_DA830_EVM) += board-da830-evm.o > > obj-$(CONFIG_MACH_DAVINCI_DA850_EVM) += board-da850-evm.o > > +obj-$(CONFIG_MACH_TNETV107X) += board-tnetv107x-evm.o > > > > # Power Management > > obj-$(CONFIG_CPU_FREQ) += cpufreq.o > > diff --git a/arch/arm/mach-davinci/board-tnetv107x-evm.c > b/arch/arm/mach-davinci/board-tnetv107x-evm.c > > new file mode 100644 > > index 0000000..a6bf49c > > --- /dev/null > > +++ b/arch/arm/mach-davinci/board-tnetv107x-evm.c > > [...] > > > +static __init void tnetv107x_evm_board_init(void) > > +{ > > + int status; > > + > > + davinci_cfg_reg_list(tnetv107x_sdio1_pins); > > + davinci_cfg_reg_list(tnetv107x_uart1_pins); > > + davinci_cfg_reg_list(tnetv107x_gpio_pins); > > + > > + tnetv107x_gpio_init(); > > + tnetv107x_edma_init(); > > + tnetv107x_serial_init(tnetv107x_serial_pdata); > > + > > + status = gpio_request(TNETV107X_EVM_MMC_WP_GPIO, "MMC WP\n"); > > + if (status < 0) { > > + printk(KERN_ERR "cannot open mmcsd write protect gpio > %d\n", > > + TNETV107X_EVM_MMC_WP_GPIO); > > + tnetv107x_evm_mmc_config.get_ro = NULL; > > + } else > > + gpio_direction_input(TNETV107X_EVM_MMC_WP_GPIO); > > Use braces on else here.. > > > + > > + status = gpio_request(TNETV107X_EVM_MMC_CD_GPIO, "MMC CD\n"); > > + if (status < 0) { > > + printk(KERN_ERR "cannot open mmcsd card detect gpio %d\n", > > + TNETV107X_EVM_MMC_CD_GPIO); > > + tnetv107x_evm_mmc_config.get_cd = NULL; > > + } else > > + gpio_direction_input(TNETV107X_EVM_MMC_CD_GPIO); > > ... and here. > > > + > > + platform_add_devices(tnetv107x_evm_devices, > > + ARRAY_SIZE(tnetv107x_evm_devices)); > > No need to mux the CD and WP pins as GPIO pins? > > Thanks, > Sekhar > > > > ------------------------------ > > Message: 6 > Date: Mon, 5 Apr 2010 16:54:47 +0530 > From: "Nori, Sekhar" > To: Andreas Auer > Cc: "davinci-linux-open-source at linux.davincidsp.com" > > Subject: RE: DM6446 and DSA (Distributed Switch Architecture) > Message-ID: > > Content-Type: text/plain; charset="us-ascii" > > > Hi Andreas, > > On Fri, Apr 02, 2010 at 14:28:15, Andreas Auer wrote: > > Steve Chen schrieb: > > > On Wed, Mar 31, 2010 at 2:44 AM, Andreas Auer > wrote: > > >> Hello, > > >> > > >> I'm using a customized board similar to the EVM with a DM6446 cpu. The > main > > >> difference is that I'm using a Micrel KSZ8893M ethernet switch. The > ethernet > > >> switch has an I2C config interface and the standard mdio interface. > > >> Therefore, I'm using the DSA driver subsystem and wrote a small chip > driver > > >> (I took the KSZ8893 driver for the Blackfin processor as reference). > > >> Now, my problem is that the ethernet mac of the Davinci cpu is > initialized > > >> (probed) later then the DSA driver. And therefore the DSA driver > cannot find > > >> a valid netdevice. > > >> Does anyone know how to change the initialization order of the > devices?? > > >> Changing the order of the register_device_driver function calls has > > >> basically no influence on the init sequence. > > >> > > >> Thanks, > > >> Andreas > > > > > > Hello, > > > > > > I encounter the same issue with DA830/OMAP-l137 EVM. Instead of > > > probing PHY to get speed and duplexity, the driver just set the speed > > > and duplexity based on platform data. May want to take a look at the > > > OMAP-l137. > > > > Thanks for your answer. I got another solution. The davinci_emac driver > > calls the init function very late because of > > late_initcall(davinci_emac_init); > > > > I changed this line: > > module_init(davinci_emac_init); > > This change was made so EMAC can get initialized after > the SPI subsystem (so mac address could be fetched from > SPI flash). Seems like there are one too many initialization > order dependencies around EMAC driver. > > Is it possible to get your DSA driver to be a late_initcall too? > Within the same initcall level the order is determined by the order > In which the makefile lists the .o file. > > Thanks, > Sekhar > > > > ------------------------------ > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source > > > End of Davinci-linux-open-source Digest, Vol 52, Issue 9 > ******************************************************** > -------------- next part -------------- An HTML attachment was scrubbed... URL: From broonie at opensource.wolfsonmicro.com Mon Apr 5 08:46:57 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Mon, 5 Apr 2010 14:46:57 +0100 Subject: [PATCH 1/4]-V2 Move TPS6507x register definition to header file. In-Reply-To: <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> Message-ID: <20100405134657.GF6580@rakim.wolfsonmicro.main> On Fri, Apr 02, 2010 at 03:37:30PM -0600, Todd Fischer wrote: > Other sub-drivers for the TPS6507x chip will need to use register > definition so move it out of the source file and into a header file. > > Signed-off-by: Todd Fischer Acked-by: Mark Brown From broonie at opensource.wolfsonmicro.com Mon Apr 5 08:48:31 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Mon, 5 Apr 2010 14:48:31 +0100 Subject: [PATCH 2/4]-V2 Make room for other tps6507x drivers to have board specific initialization data. In-Reply-To: <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> Message-ID: <20100405134831.GG6580@rakim.wolfsonmicro.main> On Fri, Apr 02, 2010 at 03:37:31PM -0600, Todd Fischer wrote: > Add mfd structure which refrences sub-driver initialization data. For example, > for a giving hardware implementation, the voltage regulator sub-driver > initialization data provides the mapping betten a voltage regulator and what > the output voltage is being used for. > > Signed-off-by: Todd Fischer Acked-by: Mark Brown From broonie at opensource.wolfsonmicro.com Mon Apr 5 08:49:13 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Mon, 5 Apr 2010 14:49:13 +0100 Subject: [PATCH 3/4]-V2 Cleaned up name space so each MFD sub-driver uses a different name space. In-Reply-To: <1270244253-4234-4-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-4-git-send-email-todd.fischer@ridgerun.com> Message-ID: <20100405134913.GH6580@rakim.wolfsonmicro.main> On Fri, Apr 02, 2010 at 03:37:32PM -0600, Todd Fischer wrote: > Move from using tps or tsp6507x to tps6057x_pmic in a consistent manner. > > Signed-off-by: Todd Fischer Acked-by: Mark Brown From broonie at opensource.wolfsonmicro.com Mon Apr 5 08:56:58 2010 From: broonie at opensource.wolfsonmicro.com (Mark Brown) Date: Mon, 5 Apr 2010 14:56:58 +0100 Subject: [PATCH 4/4]-V2 Add MFD driver for TPS6507x family of multi-function chips and move TPS6507x regulator driver from being stand-alone to using the MFD driver. In-Reply-To: <1270244253-4234-5-git-send-email-todd.fischer@ridgerun.com> References: <1270244253-4234-1-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-2-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-3-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-4-git-send-email-todd.fischer@ridgerun.com> <1270244253-4234-5-git-send-email-todd.fischer@ridgerun.com> Message-ID: <20100405135657.GI6580@rakim.wolfsonmicro.main> On Fri, Apr 02, 2010 at 03:37:33PM -0600, Todd Fischer wrote: > Add MFD driver for TPS6507x family of multi-function chips. Move TPS6507x > regulator driver from being stand-alone driver to using the MFD TPS6507x driver. > > Signed-off-by: Todd Fischer One issue... > +static int tps6507x_i2c_read_device(struct tps6507x_dev *tps6507x, char reg, > + int bytes, void *dest) > +{ > + struct i2c_client *i2c = tps6507x->i2c_client; > + int ret; > + > + ret = i2c_master_send(i2c, ®, 1); > + if (ret < 0) > + return ret; > + > + ret = i2c_master_recv(i2c, dest, bytes); > + if (ret < 0) > + return ret; > + if (ret != bytes) > + return -EIO; > + return 0; > +} Your register I/O functions don't have anything protecting them against concurrent access. This isn't really an issue for the writes by themselves since they do a single transaction on the I2C bus so the I2C layer concurrency protection ought to be enough but for reads you need to send the register address first then read back the data, opening up an issue. A simple mutex in the read and write functions ought to cover this. From khilman at deeprootsystems.com Mon Apr 5 16:06:44 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 14:06:44 -0700 Subject: [PATCH 1/4] Davinci: Allow SOCs based on other ARM CPUs In-Reply-To: <1269039457-27750-1-git-send-email-cyril@ti.com> (Cyril Chemparathy's message of "Fri\, 19 Mar 2010 18\:57\:34 -0400") References: <1269039457-27750-1-git-send-email-cyril@ti.com> Message-ID: <87mxxhvcbf.fsf@deeprootsystems.com> Cyril Chemparathy writes: > Preliminary modification prior to adding support for TNETV107X based on > ARM1176. This change allows for CPUs other than ARM926T to be used for Davinci > derivative SoCs. Existing devices (DA8x and DMx) operate unchanged. > > Signed-off-by: Cyril Chemparathy > --- Thanks, this series looks good. Applying all 4 to davinci git, and queueing for 2.6.35 in davinci-next. Kevin > arch/arm/Kconfig | 1 - > arch/arm/mach-davinci/Kconfig | 2 ++ > 2 files changed, 2 insertions(+), 1 deletions(-) > > diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig > index 3b18128..2553c75 100644 > --- a/arch/arm/Kconfig > +++ b/arch/arm/Kconfig > @@ -702,7 +702,6 @@ config ARCH_U300 > > config ARCH_DAVINCI > bool "TI DaVinci" > - select CPU_ARM926T > select GENERIC_TIME > select GENERIC_CLOCKEVENTS > select GENERIC_GPIO > diff --git a/arch/arm/mach-davinci/Kconfig b/arch/arm/mach-davinci/Kconfig > index 0ebe185..0316e20 100644 > --- a/arch/arm/mach-davinci/Kconfig > +++ b/arch/arm/mach-davinci/Kconfig > @@ -7,6 +7,7 @@ config CP_INTC > bool > > config ARCH_DAVINCI_DMx > + select CPU_ARM926T > bool > > menu "TI DaVinci Implementations" > @@ -41,6 +42,7 @@ config ARCH_DAVINCI_DA850 > select ARCH_HAS_CPUFREQ > > config ARCH_DAVINCI_DA8XX > + select CPU_ARM926T > bool > > config ARCH_DAVINCI_DM365 > -- > 1.6.3.3 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From khilman at deeprootsystems.com Mon Apr 5 16:54:06 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 14:54:06 -0700 Subject: [PATCH v2 14/16] Davinci: tnetv107x gpio implementation In-Reply-To: <1269553439-14886-15-git-send-email-cyril@ti.com> (Cyril Chemparathy's message of "Thu\, 25 Mar 2010 17\:43\:57 -0400") References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> <1269553439-14886-11-git-send-email-cyril@ti.com> <1269553439-14886-12-git-send-email-cyril@ti.com> <1269553439-14886-13-git-send-email-cyril@ti.com> <1269553439-14886-14-git-send-email-cyril@ti.com> <1269553439-14886-15-git-send-email-cyril@ti.com> Message-ID: <871vetva4h.fsf@deeprootsystems.com> Cyril Chemparathy writes: > Support for tnetv107x gpio controller. Note that this controller does not use > the gpio related definitions from davinci_soc_info. > > Further, this patch modifies davinci's inlined gpio functions to range check > against davinci_soc_info contents instead of DAVINCI_N_GPIO. This way, > tnetv107x systems can define davinci_soc_info.gpio_num to 0 and bypass the > inline routines. > > Signed-off-by: Cyril Chemparathy > --- > arch/arm/mach-davinci/Makefile | 1 + > arch/arm/mach-davinci/gpio-tnetv107x.c | 155 ++++++++++++++++++++++++ > arch/arm/mach-davinci/include/mach/gpio.h | 6 +- > arch/arm/mach-davinci/include/mach/tnetv107x.h | 4 + > 4 files changed, 163 insertions(+), 3 deletions(-) > create mode 100644 arch/arm/mach-davinci/gpio-tnetv107x.c I'm not crazy about this approach. Both the existing functions and the new functions all do basically the same thing: - read base + offset - set/clear bit(s) based on GPIO# - write base + offset I think a cleaner solution to this would be to clean the existing GPIO layer of direct knowledge of register layout. Instead, convert the gpio_controller struct into struct that holds register offsets from a base. This array of offsets is what needs to be different between davinci and tnetv107x. Also, Re: locking. You shouldn't need to globally disable interrupts here. What I'm guessing you need is a mutex. Kevin From martin at ti.com Mon Apr 5 16:52:31 2010 From: martin at ti.com (Ambrose, Martin) Date: Mon, 5 Apr 2010 16:52:31 -0500 Subject: [PATCH v3 0/1] DA8XX/OMAP-L1XX: FB: Implement double buffering In-Reply-To: <1270504278-15088-1-git-send-email-martin@ti.com> References: <1270504278-15088-1-git-send-email-martin@ti.com> Message-ID: Changes from v2 patch set: . Fixed register clear sequence in isr to avoid spurious interrupt. . Removed unused wait queue variable in wait_for_vsync(). . Moved initialization of vsync_wait prior to register_framebuffer. From martin at ti.com Mon Apr 5 16:54:59 2010 From: martin at ti.com (Ambrose, Martin) Date: Mon, 5 Apr 2010 16:54:59 -0500 Subject: [PATCH v3 1/1] DA8XX/OMAP-L1XX: FB: Implement double buffering In-Reply-To: <1270504278-15088-2-git-send-email-martin@ti.com> References: <1270504278-15088-1-git-send-email-martin@ti.com>, <1270504278-15088-2-git-send-email-martin@ti.com> Message-ID: This work includes the following: . Implement handler for FBIO_WAITFORVSYNC ioctl. . Allocate the data and palette buffers separately. A consequence of this is that the palette and data loading is now done in different phases. And that the LCD must be disabled temporarily after the palette is loaded but this will only happen once after init and each time the palette is changed. I think this is OK. . Allocate two (ping and pong) framebuffers from memory. . Add pan_display handler which toggles the LCDC DMA registers between the ping and pong buffers. Signed-off-by: Martin Ambrose --- drivers/video/da8xx-fb.c | 301 +++++++++++++++++++++++++++++++++++---------- include/video/da8xx-fb.h | 1 + 2 files changed, 235 insertions(+), 67 deletions(-) diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index 8d244ba..cad7d45 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c @@ -36,7 +36,9 @@ #define DRIVER_NAME "da8xx_lcdc" /* LCD Status Register */ +#define LCD_END_OF_FRAME1 BIT(9) #define LCD_END_OF_FRAME0 BIT(8) +#define LCD_PL_LOAD_DONE BIT(6) #define LCD_FIFO_UNDERFLOW BIT(5) #define LCD_SYNC_LOST BIT(2) @@ -58,11 +60,13 @@ #define LCD_PALETTE_LOAD_MODE(x) ((x) << 20) #define PALETTE_AND_DATA 0x00 #define PALETTE_ONLY 0x01 +#define DATA_ONLY 0x02 #define LCD_MONO_8BIT_MODE BIT(9) #define LCD_RASTER_ORDER BIT(8) #define LCD_TFT_MODE BIT(7) #define LCD_UNDERFLOW_INT_ENA BIT(6) +#define LCD_PL_ENABLE BIT(4) #define LCD_MONOCHROME_MODE BIT(1) #define LCD_RASTER_ENABLE BIT(0) #define LCD_TFT_ALT_ENABLE BIT(23) @@ -87,6 +91,10 @@ #define LCD_DMA_CTRL_REG 0x40 #define LCD_DMA_FRM_BUF_BASE_ADDR_0_REG 0x44 #define LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG 0x48 +#define LCD_DMA_FRM_BUF_BASE_ADDR_1_REG 0x4C +#define LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG 0x50 + +#define LCD_NUM_BUFFERS 2 #define WSI_TIMEOUT 50 #define PALETTE_SIZE 256 @@ -111,13 +119,20 @@ static inline void lcdc_write(unsigned int val, unsigned int addr) struct da8xx_fb_par { resource_size_t p_palette_base; unsigned char *v_palette_base; + dma_addr_t vram_phys; + unsigned long vram_size; + void *vram_virt; + unsigned int dma_start; + unsigned int dma_end; struct clk *lcdc_clk; int irq; unsigned short pseudo_palette[16]; - unsigned int databuf_sz; unsigned int palette_sz; unsigned int pxl_clk; int blank; + wait_queue_head_t vsync_wait; + int vsync_flag; + int vsync_timeout; #ifdef CONFIG_CPU_FREQ struct notifier_block freq_transition; #endif @@ -148,9 +163,9 @@ static struct fb_fix_screeninfo da8xx_fb_fix __devinitdata = { .type = FB_TYPE_PACKED_PIXELS, .type_aux = 0, .visual = FB_VISUAL_PSEUDOCOLOR, - .xpanstep = 1, + .xpanstep = 0, .ypanstep = 1, - .ywrapstep = 1, + .ywrapstep = 0, .accel = FB_ACCEL_NONE }; @@ -221,22 +236,48 @@ static inline void lcd_disable_raster(void) static void lcd_blit(int load_mode, struct da8xx_fb_par *par) { - u32 tmp = par->p_palette_base + par->databuf_sz - 4; - u32 reg; + u32 start; + u32 end; + u32 reg_ras; + u32 reg_dma; + + /* init reg to clear PLM (loading mode) fields */ + reg_ras = lcdc_read(LCD_RASTER_CTRL_REG); + reg_ras &= ~(3 << 20); + + reg_dma = lcdc_read(LCD_DMA_CTRL_REG); + + if (load_mode == LOAD_DATA) { + start = par->dma_start; + end = par->dma_end; + + reg_ras |= LCD_PALETTE_LOAD_MODE(DATA_ONLY); + reg_dma |= LCD_END_OF_FRAME_INT_ENA; + reg_dma |= LCD_DUAL_FRAME_BUFFER_ENABLE; + + lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + } else if (load_mode == LOAD_PALETTE) { + start = par->p_palette_base; + end = start + par->palette_sz - 1; + + reg_ras |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); + reg_ras |= LCD_PL_ENABLE; + + lcdc_write(start, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(end, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + } - /* Update the databuf in the hw. */ - lcdc_write(par->p_palette_base, LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); - lcdc_write(tmp, LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + lcdc_write(reg_dma, LCD_DMA_CTRL_REG); + lcdc_write(reg_ras, LCD_RASTER_CTRL_REG); - /* Start the DMA. */ - reg = lcdc_read(LCD_RASTER_CTRL_REG); - reg &= ~(3 << 20); - if (load_mode == LOAD_DATA) - reg |= LCD_PALETTE_LOAD_MODE(PALETTE_AND_DATA); - else if (load_mode == LOAD_PALETTE) - reg |= LCD_PALETTE_LOAD_MODE(PALETTE_ONLY); - - lcdc_write(reg, LCD_RASTER_CTRL_REG); + /* + * The Raster enable bit must be set after all other control fields are + * set. + */ + lcd_enable_raster(); } /* Configure the Burst Size of DMA */ @@ -368,12 +409,8 @@ static int lcd_cfg_display(const struct lcd_ctrl_config *cfg) static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, u32 bpp, u32 raster_order) { - u32 bpl, reg; + u32 reg; - /* Disable Dual Frame Buffer. */ - reg = lcdc_read(LCD_DMA_CTRL_REG); - lcdc_write(reg & ~LCD_DUAL_FRAME_BUFFER_ENABLE, - LCD_DMA_CTRL_REG); /* Set the Panel Width */ /* Pixels per line = (PPL + 1)*16 */ /*0x3F in bits 4..9 gives max horisontal resolution = 1024 pixels*/ @@ -410,9 +447,6 @@ static int lcd_cfg_frame_buffer(struct da8xx_fb_par *par, u32 width, u32 height, return -EINVAL; } - bpl = width * bpp / 8; - par->databuf_sz = height * bpl + par->palette_sz; - return 0; } @@ -421,8 +455,9 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, struct fb_info *info) { struct da8xx_fb_par *par = info->par; - unsigned short *palette = (unsigned short *)par->v_palette_base; + unsigned short *palette = (unsigned short *) par->v_palette_base; u_short pal; + int update_hw = 0; if (regno > 255) return 1; @@ -439,8 +474,10 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, pal |= (green & 0x00f0); pal |= (blue & 0x000f); - palette[regno] = pal; - + if (palette[regno] != pal) { + update_hw = 1; + palette[regno] = pal; + } } else if ((info->var.bits_per_pixel == 16) && regno < 16) { red >>= (16 - info->var.red.length); red <<= info->var.red.offset; @@ -453,9 +490,16 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, par->pseudo_palette[regno] = red | green | blue; - palette[0] = 0x4000; + if (palette[0] != 0x4000) { + update_hw = 1; + palette[0] = 0x4000; + } } + /* Update the palette in the h/w as needed. */ + if (update_hw) + lcd_blit(LOAD_PALETTE, par); + return 0; } @@ -541,15 +585,54 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, static irqreturn_t lcdc_irq_handler(int irq, void *arg) { + struct da8xx_fb_par *par = arg; u32 stat = lcdc_read(LCD_STAT_REG); + u32 reg_ras; if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { lcd_disable_raster(); lcdc_write(stat, LCD_STAT_REG); lcd_enable_raster(); - } else + } else if (stat & LCD_PL_LOAD_DONE) { + /* + * Must disable raster before changing state of any control bit. + * And also must be disabled before clearing the PL loading + * interrupt via the following write to the status register. If + * this is done after then one gets multiple PL done interrupts. + */ + lcd_disable_raster(); + lcdc_write(stat, LCD_STAT_REG); + /* Disable PL completion inerrupt */ + reg_ras = lcdc_read(LCD_RASTER_CTRL_REG); + reg_ras &= ~LCD_PL_ENABLE; + lcdc_write(reg_ras, LCD_RASTER_CTRL_REG); + + /* Setup and start data loading mode */ + lcd_blit(LOAD_DATA, par); + } else { + lcdc_write(stat, LCD_STAT_REG); + + if (stat & LCD_END_OF_FRAME0) { + lcdc_write(par->dma_start, + LCD_DMA_FRM_BUF_BASE_ADDR_0_REG); + lcdc_write(par->dma_end, + LCD_DMA_FRM_BUF_CEILING_ADDR_0_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); + } + + if (stat & LCD_END_OF_FRAME1) { + lcdc_write(par->dma_start, + LCD_DMA_FRM_BUF_BASE_ADDR_1_REG); + lcdc_write(par->dma_end, + LCD_DMA_FRM_BUF_CEILING_ADDR_1_REG); + par->vsync_flag = 1; + wake_up_interruptible(&par->vsync_wait); + } + } + return IRQ_HANDLED; } @@ -654,9 +737,10 @@ static int __devexit fb_remove(struct platform_device *dev) unregister_framebuffer(info); fb_dealloc_cmap(&info->cmap); - dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, - info->screen_base - PAGE_SIZE, - info->fix.smem_start); + dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base, + par->p_palette_base); + dma_free_coherent(NULL, par->vram_size, par->vram_virt, + par->vram_phys); free_irq(par->irq, par); clk_disable(par->lcdc_clk); clk_put(par->lcdc_clk); @@ -668,6 +752,39 @@ static int __devexit fb_remove(struct platform_device *dev) return 0; } +/* + * Function to wait for vertical sync which for this LCD peripheral + * translates into waiting for the current raster frame to complete. + */ +static int fb_wait_for_vsync(struct fb_info *info) +{ + struct da8xx_fb_par *par = info->par; + int ret; + + /* + * Set flag to 0 and wait for isr to set to 1. It would seem there is a + * race condition here where the ISR could have occured just before or + * just after this set. But since we are just coarsely waiting for + * a frame to complete then that's OK. i.e. if the frame completed + * just before this code executed then we have to wait another full + * frame time but there is no way to avoid such a situation. On the + * other hand if the frame completed just after then we don't need + * to wait long at all. Either way we are guaranteed to return to the + * user immediately after a frame completion which is all that is + * required. + */ + par->vsync_flag = 0; + ret = wait_event_interruptible_timeout(par->vsync_wait, + par->vsync_flag != 0, + par->vsync_timeout); + if (ret < 0) + return ret; + if (ret == 0) + return -ETIMEDOUT; + + return 0; +} + static int fb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) { @@ -697,6 +814,8 @@ static int fb_ioctl(struct fb_info *info, unsigned int cmd, sync_arg.pulse_width, sync_arg.front_porch); break; + case FBIO_WAITFORVSYNC: + return fb_wait_for_vsync(info); default: return -EINVAL; } @@ -732,10 +851,47 @@ static int cfb_blank(int blank, struct fb_info *info) return ret; } +/* + * Set new x,y offsets in the virtual display for the visible area and switch + * to the new mode. + */ +static int da8xx_pan_display(struct fb_var_screeninfo *var, + struct fb_info *fbi) +{ + int ret = 0; + struct fb_var_screeninfo new_var; + struct da8xx_fb_par *par = fbi->par; + struct fb_fix_screeninfo *fix = &fbi->fix; + unsigned int end; + unsigned int start; + + if (var->xoffset != fbi->var.xoffset || + var->yoffset != fbi->var.yoffset) { + memcpy(&new_var, &fbi->var, sizeof(new_var)); + new_var.xoffset = var->xoffset; + new_var.yoffset = var->yoffset; + if (fb_check_var(&new_var, fbi)) + ret = -EINVAL; + else { + memcpy(&fbi->var, &new_var, sizeof(new_var)); + + start = fix->smem_start + + new_var.yoffset * fix->line_length + + new_var.xoffset * var->bits_per_pixel / 8; + end = start + var->yres * fix->line_length - 1; + par->dma_start = start; + par->dma_end = end; + } + } + + return ret; +} + static struct fb_ops da8xx_fb_ops = { .owner = THIS_MODULE, .fb_check_var = fb_check_var, .fb_setcolreg = fb_setcolreg, + .fb_pan_display = da8xx_pan_display, .fb_ioctl = fb_ioctl, .fb_fillrect = cfb_fillrect, .fb_copyarea = cfb_copyarea, @@ -829,40 +985,53 @@ static int __init fb_probe(struct platform_device *device) } /* allocate frame buffer */ - da8xx_fb_info->screen_base = dma_alloc_coherent(NULL, - par->databuf_sz + PAGE_SIZE, - (resource_size_t *) - &da8xx_fb_info->fix.smem_start, - GFP_KERNEL | GFP_DMA); - - if (!da8xx_fb_info->screen_base) { + par->vram_size = lcdc_info->width * lcdc_info->height * lcd_cfg->bpp; + par->vram_size = PAGE_ALIGN(par->vram_size/8); + par->vram_size = par->vram_size * LCD_NUM_BUFFERS; + + par->vram_virt = dma_alloc_coherent(NULL, + par->vram_size, + (resource_size_t *) &par->vram_phys, + GFP_KERNEL | GFP_DMA); + if (!par->vram_virt) { dev_err(&device->dev, "GLCD: kmalloc for frame buffer failed\n"); ret = -EINVAL; goto err_release_fb; } - /* move palette base pointer by (PAGE_SIZE - palette_sz) bytes */ - par->v_palette_base = da8xx_fb_info->screen_base + - (PAGE_SIZE - par->palette_sz); - par->p_palette_base = da8xx_fb_info->fix.smem_start + - (PAGE_SIZE - par->palette_sz); - - /* the rest of the frame buffer is pixel data */ - da8xx_fb_info->screen_base = par->v_palette_base + par->palette_sz; - da8xx_fb_fix.smem_start = par->p_palette_base + par->palette_sz; - da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz; - da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; + da8xx_fb_info->screen_base = (char __iomem *) par->vram_virt; + da8xx_fb_fix.smem_start = par->vram_phys; + da8xx_fb_fix.smem_len = par->vram_size; + da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; + + par->dma_start = par->vram_phys; + par->dma_end = par->dma_start + lcdc_info->height * + da8xx_fb_fix.line_length - 1; + + /* allocate palette buffer */ + par->v_palette_base = dma_alloc_coherent(NULL, + PALETTE_SIZE, + (resource_size_t *) + &par->p_palette_base, + GFP_KERNEL | GFP_DMA); + if (!par->v_palette_base) { + dev_err(&device->dev, + "GLCD: kmalloc for palette buffer failed\n"); + ret = -EINVAL; + goto err_release_fb_mem; + } + memset(par->v_palette_base, 0, PALETTE_SIZE); par->irq = platform_get_irq(device, 0); if (par->irq < 0) { ret = -ENOENT; - goto err_release_fb_mem; + goto err_release_pl_mem; } ret = request_irq(par->irq, lcdc_irq_handler, 0, DRIVER_NAME, par); if (ret) - goto err_release_fb_mem; + goto err_release_pl_mem; /* Initialize par */ da8xx_fb_info->var.bits_per_pixel = lcd_cfg->bpp; @@ -870,8 +1039,8 @@ static int __init fb_probe(struct platform_device *device) da8xx_fb_var.xres = lcdc_info->width; da8xx_fb_var.xres_virtual = lcdc_info->width; - da8xx_fb_var.yres = lcdc_info->height; - da8xx_fb_var.yres_virtual = lcdc_info->height; + da8xx_fb_var.yres = lcdc_info->height; + da8xx_fb_var.yres_virtual = lcdc_info->height * LCD_NUM_BUFFERS; da8xx_fb_var.grayscale = lcd_cfg->p_disp_panel->panel_shade == MONOCHROME ? 1 : 0; @@ -892,18 +1061,18 @@ static int __init fb_probe(struct platform_device *device) ret = fb_alloc_cmap(&da8xx_fb_info->cmap, PALETTE_SIZE, 0); if (ret) goto err_free_irq; - - /* First palette_sz byte of the frame buffer is the palette */ da8xx_fb_info->cmap.len = par->palette_sz; - /* Flush the buffer to the screen. */ - lcd_blit(LOAD_DATA, par); - /* initialize var_screeninfo */ da8xx_fb_var.activate = FB_ACTIVATE_FORCE; fb_set_var(da8xx_fb_info, &da8xx_fb_var); dev_set_drvdata(&device->dev, da8xx_fb_info); + + /* initialize the vsync wait queue */ + init_waitqueue_head(&par->vsync_wait); + par->vsync_timeout = HZ / 5; + /* Register the Frame Buffer */ if (register_framebuffer(da8xx_fb_info) < 0) { dev_err(&device->dev, @@ -919,10 +1088,6 @@ static int __init fb_probe(struct platform_device *device) goto err_cpu_freq; } #endif - - /* enable raster engine */ - lcd_enable_raster(); - return 0; #ifdef CONFIG_CPU_FREQ @@ -936,10 +1101,12 @@ err_dealloc_cmap: err_free_irq: free_irq(par->irq, par); +err_release_pl_mem: + dma_free_coherent(NULL, PALETTE_SIZE, par->v_palette_base, + par->p_palette_base); + err_release_fb_mem: - dma_free_coherent(NULL, par->databuf_sz + PAGE_SIZE, - da8xx_fb_info->screen_base - PAGE_SIZE, - da8xx_fb_info->fix.smem_start); + dma_free_coherent(NULL, par->vram_size, par->vram_virt, par->vram_phys); err_release_fb: framebuffer_release(da8xx_fb_info); diff --git a/include/video/da8xx-fb.h b/include/video/da8xx-fb.h index 89d43b3..6316cda 100644 --- a/include/video/da8xx-fb.h +++ b/include/video/da8xx-fb.h @@ -99,6 +99,7 @@ struct lcd_sync_arg { #define FBIPUT_COLOR _IOW('F', 6, int) #define FBIPUT_HSYNC _IOW('F', 9, int) #define FBIPUT_VSYNC _IOW('F', 10, int) +#define FBIO_WAITFORVSYNC _IOW('F', 0x20, u_int32_t) #endif /* ifndef DA8XX_FB_H */ -- 1.6.6.1 From khilman at deeprootsystems.com Mon Apr 5 17:06:10 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 15:06:10 -0700 Subject: [PATCH 13/14] Davinci: simplified debug macros In-Reply-To: (Sekhar Nori's message of "Thu\, 25 Mar 2010 21\:58\:04 +0530") References: <1269476345-16111-1-git-send-email-cyril@ti.com> <1269476345-16111-2-git-send-email-cyril@ti.com> <1269476345-16111-3-git-send-email-cyril@ti.com> <1269476345-16111-4-git-send-email-cyril@ti.com> <1269476345-16111-5-git-send-email-cyril@ti.com> <1269476345-16111-6-git-send-email-cyril@ti.com> <1269476345-16111-7-git-send-email-cyril@ti.com> <1269476345-16111-8-git-send-email-cyril@ti.com> <1269476345-16111-9-git-send-email-cyril@ti.com> <1269476345-16111-10-git-send-email-cyril@ti.com> <1269476345-16111-11-git-send-email-cyril@ti.com> <1269476345-16111-12-git-send-email-cyril@ti.com> <1269476345-16111-13-git-send-email-cyril@ti.com> <1269476345-16111-14-git-send-email-cyril@ti.com> <4BAB408A.7040706@mvista.com> <8FFAA0BFC4E5374B8F85F65FE1F2BFA58B937985@dlee02.ent.ti.com> Message-ID: <87pr2dtuzx.fsf@deeprootsystems.com> "Nori, Sekhar" writes: > On Thu, Mar 25, 2010 at 20:39:02, Chemparathy, Cyril wrote: >> Sergei, >> >> [...] >> > > > +#if defined(CONFIG_ARCH_DAVINCI_DMx) >> > > > +#define UART_PHYS DAVINCI_UART0_BASE >> > > > +#define UART_VIRT IO_ADDRESS(UART_PHYS) >> > > > +#endif >> > > >> > > These UART addressed are machine-, not arch-specific. >> > >> > Thanks. Will change in v2. >> >> On second thoughts, if we were to make these definitions machine specific, it would explode into excruciating verbosity: >> >> #if defined(CONFIG_MACH_DAVINCI_EVM) || \ >> defined(CONFIG_MACH_SFFSDR) || \ >> defined(CONFIG_MACH_NEUROS_OSD2) || \ >> defined(CONFIG_MACH_DAVINCI_DM355_EVM) || \ >> defined(CONFIG_MACH_DM355_LEOPARD) || \ >> defined(CONFIG_MACH_DAVINCI_DM6467_EVM) || \ >> defined(CONFIG_MACH_DAVINCI_DM6467TEVM) || \ >> defined(CONFIG_MACH_DAVINCI_DM365_EVM) >> >> Is that the preferred approach? Would we be better off leaving UART selection arch-specific for now and making it machine-specific as and when a new board deviates from the norm on that arch? >> > > How about trying to do some runtime detection of the enabled > UART by checking the enabled status in PWREMU_MGMT register of > each UART starting from UART0. You would probably also need a > fall-back option that can be chosen by boards on which this is > guaranteed not to work (they can provide the debug UART# in kernel > configuration). > > I quickly checked DM644x and OMAP-L138 documentation and both > of these have the register implemented and have the UART reset > by default. > > OMAP2/3 seems to manage this by writing a pattern to the UART SCR > registers, but unfortunately none of the DaVinci bootloaders > support this. Actually, we don't need bootloader support for this. On OMAP, we do this in the uncompress code. See: arch/arm/plat-omap/include/plat/uncompress.h, and in this commit[1] for details. Rather than continuing to hack the current hack, I'd like to see something similar on DaVinci. This will also remove one more barrier to multiple-SoC support. Also, we don't necessarily have to use the UART1 scratchpad register. All we need is some temporary, writable register that is available on all supported SoCs. Any suggestions? Kevin [1] commit 0c8219f0302d0d27fda52c790d38406801e547ec Author: Tony Lindgren Date: Mon Feb 15 08:49:01 2010 -0800 omap: Make uncompress code and DEBUG_LL code generic Define arch_decomp_setup() the same way as some other architectures do. Use arch_id to configure the debug uart based on the machine_is by storing it into the uart scratchpad register for DEBUG_LL code to use. Signed-off-by: Tony Lindgren From khilman at deeprootsystems.com Mon Apr 5 17:07:24 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 15:07:24 -0700 Subject: [PATCH v2 09/16] Davinci: tnetv107x SOC specific header In-Reply-To: (Sekhar Nori's message of "Mon\, 5 Apr 2010 11\:48\:20 +0530") References: <1269553439-14886-1-git-send-email-cyril@ti.com> <1269553439-14886-2-git-send-email-cyril@ti.com> <1269553439-14886-3-git-send-email-cyril@ti.com> <1269553439-14886-4-git-send-email-cyril@ti.com> <1269553439-14886-5-git-send-email-cyril@ti.com> <1269553439-14886-6-git-send-email-cyril@ti.com> <1269553439-14886-7-git-send-email-cyril@ti.com> <1269553439-14886-8-git-send-email-cyril@ti.com> <1269553439-14886-9-git-send-email-cyril@ti.com> <1269553439-14886-10-git-send-email-cyril@ti.com> Message-ID: <87k4sltuxv.fsf@deeprootsystems.com> "Nori, Sekhar" writes: > On Fri, Mar 26, 2010 at 03:13:52, Chemparathy, Cyril wrote: >> Added on-chip peripheral base addresses so tnetv107x SOC header. >> > > There should be no need to define the full > list of base addresses in one place because > the are typically needed only at only one place > (near the resource definition). > > Just add the define where needed and use it. Agreed. These should only ever be used when defining a platform_device or in the low-level core code. Kevin From khilman at deeprootsystems.com Mon Apr 5 17:12:21 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 15:12:21 -0700 Subject: [PATCH] Add touch screen input driver for TPS6507x family of multi-function chips. In-Reply-To: <1270336600-1664-1-git-send-email-todd.fischer@ridgerun.com> (Todd Fischer's message of "Sat\, 3 Apr 2010 17\:16\:40 -0600") References: <1270336600-1664-1-git-send-email-todd.fischer@ridgerun.com> Message-ID: <87eiittupm.fsf@deeprootsystems.com> Todd Fischer writes: > The TPS6507x family of Texas Instruments power management ICs (pmic) > are multi-function chips that include voltage regulation and touch > screen controller capabilities. This patch adds a touch screen > input driver for the TPS6507x pmic. There was an existing regulator > driver. Before the touch screen driver could be added, a multi-function > device (MFD) driver was needed and the regulator driver modified to > use the MDF driver. Patches for these changes have been posted and > reviewed. The TPS6507x touch screen driver applies cleanly to the > MFD GIT repo after the above referenced patches are applied. If I > should use a different approach for the touch screen driver, please > let me know. > > Signed-off-by: Todd Fischer > --- > arch/arm/mach-davinci/board-da850-evm.c | 12 + Could you separate out the da850 board support from the driver please? To avoid convlicts with other arch code, I will merge the board support via davinci git after the driver is merged via the appropriate subsystem tree. Kevin > drivers/input/touchscreen/Kconfig | 13 + > drivers/input/touchscreen/Makefile | 1 + > drivers/input/touchscreen/tps6507x-ts.c | 400 +++++++++++++++++++++++++++++++ > drivers/mfd/tps6507x.c | 3 + > include/linux/input/tps6507x-ts.h | 24 ++ > include/linux/mfd/tps6507x.h | 2 + > 7 files changed, 455 insertions(+), 0 deletions(-) > create mode 100644 drivers/input/touchscreen/tps6507x-ts.c > create mode 100644 include/linux/input/tps6507x-ts.h > > diff --git a/arch/arm/mach-davinci/board-da850-evm.c b/arch/arm/mach-davinci/board-da850-evm.c > index d059924..b3cbb32 100644 > --- a/arch/arm/mach-davinci/board-da850-evm.c > +++ b/arch/arm/mach-davinci/board-da850-evm.c > @@ -25,6 +25,8 @@ > #include > #include > #include > +#include > +#include > > #include > #include > @@ -534,8 +536,18 @@ struct regulator_init_data tps65070_regulator_data[] = { > }, > }; > > +static struct touchscreen_init_data tps6507x_touchscreen_data = { > + .poll_period = 30, /* ms between touch samples */ > + .min_pressure = 0x30, /* minimum pressure to trigger touch */ > + .vref = 0, /* turn off vref when not using A/D */ > + .vendor = 0, /* /sys/class/input/input?/id/vendor */ > + .product = 65070, /* /sys/class/input/input?/id/product */ > + .version = 0x100, /* /sys/class/input/input?/id/version */ > +}; > + > static struct tps6507x_board tps_board = { > .tps6507x_pmic_init_data = &tps65070_regulator_data[0], > + .tps6507x_ts_init_data = &tps6507x_touchscreen_data, > }; > > static struct i2c_board_info __initdata da850evm_tps65070_info[] = { > diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig > index 8a8fa4d..6166aa8 100644 > --- a/drivers/input/touchscreen/Kconfig > +++ b/drivers/input/touchscreen/Kconfig > @@ -594,4 +594,17 @@ config TOUCHSCREEN_PCAP > > To compile this driver as a module, choose M here: the > module will be called pcap_ts. > + > +config TOUCHSCREEN_TPS6507X > + tristate "TPS6507x based touchscreens" > + depends on I2C > + help > + Say Y here if you have a TPS6507x based touchscreen > + controller. > + > + If unsure, say N. > + > + To compile this driver as a module, choose M here: the > + module will be called tps6507x_ts. > + > endif > diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile > index 7fef7d5..cfa83d0 100644 > --- a/drivers/input/touchscreen/Makefile > +++ b/drivers/input/touchscreen/Makefile > @@ -46,3 +46,4 @@ obj-$(CONFIG_TOUCHSCREEN_WM97XX_ATMEL) += atmel-wm97xx.o > obj-$(CONFIG_TOUCHSCREEN_WM97XX_MAINSTONE) += mainstone-wm97xx.o > obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o > obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o > +obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o > diff --git a/drivers/input/touchscreen/tps6507x-ts.c b/drivers/input/touchscreen/tps6507x-ts.c > new file mode 100644 > index 0000000..5de80a1 > --- /dev/null > +++ b/drivers/input/touchscreen/tps6507x-ts.c > @@ -0,0 +1,400 @@ > +/* > + * drivers/input/touchscreen/tps6507x_ts.c > + * > + * Touchscreen driver for the tps6507x chip. > + * > + * Copyright (c) 2009 RidgeRun (todd.fischer at ridgerun.com) > + * > + * Credits: > + * > + * Using code from tsc2007, MtekVision Co., Ltd. > + * > + * For licencing details see kernel-base/COPYING > + * > + * TPS65070, TPS65073, TPS650731, and TPS650732 support > + * 10 bit touch screen interface. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +#define TSC_DEFAULT_POLL_PERIOD 30 /* ms */ > +#define TPS_DEFAULT_MIN_PRESSURE 0x30 > +#define MAX_10BIT ((1 << 10) - 1) > + > +#define TPS6507X_ADCONFIG_CONVERT_TS (TPS6507X_ADCONFIG_AD_ENABLE | \ > + TPS6507X_ADCONFIG_START_CONVERSION | \ > + TPS6507X_ADCONFIG_INPUT_REAL_TSC) > +#define TPS6507X_ADCONFIG_POWER_DOWN_TS (TPS6507X_ADCONFIG_INPUT_REAL_TSC) > + > +struct ts_event { > + u16 x; > + u16 y; > + u16 pressure; > +}; > + > +struct tps6507x_ts { > + struct input_dev *input_dev; > + struct device *dev; > + char phys[32]; > + struct workqueue_struct *wq; > + struct delayed_work work; > + unsigned polling; /* polling is active */ > + struct ts_event tc; > + struct tps6507x_dev *mfd; > + u16 model; > + unsigned pendown; > + int irq; > + void (*clear_penirq)(void); > + unsigned long poll_period; /* ms */ > + u16 min_pressure; > + int vref; /* non-zero to leave vref on */ > +}; > + > +static int tps6507x_read_u8(struct tps6507x_ts *tsc, u8 reg, u8 *data) > +{ > + int err; > + > + err = tsc->mfd->read_dev(tsc->mfd, reg, 1, data); > + > + if (err) > + return err; > + > + return 0; > +} > + > +static int tps6507x_write_u8(struct tps6507x_ts *tsc, u8 reg, u8 data) > +{ > + return tsc->mfd->write_dev(tsc->mfd, reg, 1, &data); > +} > + > +static s32 tps6507x_adc_conversion(struct tps6507x_ts *tsc, > + u8 tsc_mode, u16 *value) > +{ > + s32 ret; > + u8 adc_status; > + u8 result; > + > + /* Route input signal to A/D converter */ > + > + ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, tsc_mode); > + if (ret) { > + dev_err(tsc->dev, "TSC mode read failed\n"); > + goto err; > + } > + > + /* Start A/D conversion */ > + > + ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, > + TPS6507X_ADCONFIG_CONVERT_TS); > + if (ret) { > + dev_err(tsc->dev, "ADC config write failed\n"); > + return ret; > + } > + > + do { > + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADCONFIG, > + &adc_status); > + if (ret) { > + dev_err(tsc->dev, "ADC config read failed\n"); > + goto err; > + } > + } while (adc_status & TPS6507X_ADCONFIG_START_CONVERSION); > + > + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_2, &result); > + if (ret) { > + dev_err(tsc->dev, "ADC result 2 read failed\n"); > + goto err; > + } > + > + *value = (result & TPS6507X_REG_ADRESULT_2_MASK) << 8; > + > + ret = tps6507x_read_u8(tsc, TPS6507X_REG_ADRESULT_1, &result); > + if (ret) { > + dev_err(tsc->dev, "ADC result 1 read failed\n"); > + goto err; > + } > + > + *value |= result; > + > + dev_dbg(tsc->dev, "TSC channel %d = 0x%X\n", tsc_mode, *value); > + > +err: > + return ret; > +} > + > +/* Need to call tps6507x_adc_standby() after using A/D converter for the > + * touch screen interrupt to work properly. > + */ > + > +static s32 tps6507x_adc_standby(struct tps6507x_ts *tsc) > +{ > + s32 ret; > + s32 loops = 0; > + u8 val; > + > + ret = tps6507x_write_u8(tsc, TPS6507X_REG_ADCONFIG, > + TPS6507X_ADCONFIG_INPUT_TSC); > + if (ret) > + return ret; > + > + ret = tps6507x_write_u8(tsc, TPS6507X_REG_TSCMODE, > + TPS6507X_TSCMODE_STANDBY); > + if (ret) > + return ret; > + > + ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); > + if (ret) > + return ret; > + > + while (val & TPS6507X_REG_TSC_INT) { > + mdelay(10); > + ret = tps6507x_read_u8(tsc, TPS6507X_REG_INT, &val); > + if (ret) > + return ret; > + loops++; > + } > + > + return ret; > +} > + > +static void tps6507x_ts_handler(struct work_struct *work) > +{ > + struct tps6507x_ts *tsc = container_of(work, > + struct tps6507x_ts, work.work); > + struct input_dev *input_dev = tsc->input_dev; > + int pendown; > + int schd; > + int poll = 0; > + s32 ret; > + > + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_PRESSURE, > + &tsc->tc.pressure); > + if (ret) > + goto done; > + > + pendown = tsc->tc.pressure > tsc->min_pressure; > + > + if (unlikely(!pendown && tsc->pendown)) { > + dev_dbg(tsc->dev, "UP\n"); > + input_report_key(input_dev, BTN_TOUCH, 0); > + input_report_abs(input_dev, ABS_PRESSURE, 0); > + input_sync(input_dev); > + tsc->pendown = 0; > + } > + > + if (pendown) { > + > + if (!tsc->pendown) { > + dev_dbg(tsc->dev, "DOWN\n"); > + input_report_key(input_dev, BTN_TOUCH, 1); > + } else > + dev_dbg(tsc->dev, "still down\n"); > + > + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_X_POSITION, > + &tsc->tc.x); > + if (ret) > + goto done; > + > + ret = tps6507x_adc_conversion(tsc, TPS6507X_TSCMODE_Y_POSITION, > + &tsc->tc.y); > + if (ret) > + goto done; > + > + input_report_abs(input_dev, ABS_X, tsc->tc.x); > + input_report_abs(input_dev, ABS_Y, tsc->tc.y); > + input_report_abs(input_dev, ABS_PRESSURE, tsc->tc.pressure); > + input_sync(input_dev); > + tsc->pendown = 1; > + poll = 1; > + } > + > +done: > + /* always poll if not using interrupts */ > + poll = 1; > + > + if (poll) { > + schd = queue_delayed_work(tsc->wq, &tsc->work, > + tsc->poll_period * HZ / 1000); > + if (schd) > + tsc->polling = 1; > + else { > + tsc->polling = 0; > + dev_err(tsc->dev, "re-schedule failed"); > + } > + } else > + tsc->polling = 0; > + > + ret = tps6507x_adc_standby(tsc); > +} > + > +static int tps6507x_ts_probe(struct platform_device *pdev) > +{ > + int error; > + struct tps6507x_ts *tsc; > + struct tps6507x_dev *tps6507x_dev = dev_get_drvdata(pdev->dev.parent); > + struct touchscreen_init_data *init_data; > + struct input_dev *input_dev; > + struct tps6507x_board *tps_board; > + int schd; > + > + /** > + * tps_board points to pmic related constants > + * coming from the board-evm file. > + */ > + > + tps_board = (struct tps6507x_board *)tps6507x_dev->dev->platform_data; > + > + if (!tps_board) { > + dev_err(tps6507x_dev->dev, > + "Could not find tps6507x platform data\n"); > + return -EIO; > + } > + > + /** > + * init_data points to array of regulator_init structures > + * coming from the board-evm file. > + */ > + > + init_data = tps_board->tps6507x_ts_init_data; > + > + tsc = kzalloc(sizeof(struct tps6507x_ts), GFP_KERNEL); > + if (!tsc) { > + dev_err(tps6507x_dev->dev, "failed to allocate driver data\n"); > + error = -ENOMEM; > + goto err0; > + } > + > + tps6507x_dev->ts = tsc; > + tsc->mfd = tps6507x_dev; > + tsc->dev = tps6507x_dev->dev; > + input_dev = input_allocate_device(); > + if (!input_dev) { > + dev_err(tsc->dev, "Failed to allocate input device.\n"); > + error = -ENOMEM; > + goto err1; > + } > + > + input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); > + input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); > + > + input_set_abs_params(input_dev, ABS_X, 0, MAX_10BIT, 0, 0); > + input_set_abs_params(input_dev, ABS_Y, 0, MAX_10BIT, 0, 0); > + input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_10BIT, 0, 0); > + > + input_dev->name = "TPS6507x Touchscreen"; > + input_dev->id.bustype = BUS_I2C; > + input_dev->dev.parent = tsc->dev; > + > + snprintf(tsc->phys, sizeof(tsc->phys), > + "%s/input0", dev_name(tsc->dev)); > + input_dev->phys = tsc->phys; > + > + dev_dbg(tsc->dev, "device: %s\n", input_dev->phys); > + > + input_set_drvdata(input_dev, tsc); > + > + tsc->input_dev = input_dev; > + > + INIT_DELAYED_WORK(&tsc->work, tps6507x_ts_handler); > + tsc->wq = create_workqueue("TPS6507x Touchscreen"); > + > + if (init_data) { > + tsc->poll_period = init_data->poll_period; > + tsc->vref = init_data->vref; > + tsc->min_pressure = init_data->min_pressure; > + input_dev->id.vendor = init_data->vendor; > + input_dev->id.product = init_data->product; > + input_dev->id.version = init_data->version; > + } else { > + tsc->poll_period = TSC_DEFAULT_POLL_PERIOD; > + tsc->min_pressure = TPS_DEFAULT_MIN_PRESSURE; > + } > + > + error = tps6507x_adc_standby(tsc); > + if (error) > + goto err2; > + > + error = input_register_device(input_dev); > + if (error) > + goto err2; > + > + schd = queue_delayed_work(tsc->wq, &tsc->work, > + tsc->poll_period * HZ / 1000); > + > + if (schd) > + tsc->polling = 1; > + else { > + tsc->polling = 0; > + dev_err(tsc->dev, "schedule failed"); > + goto err2; > + } > + > + return 0; > + > +err2: > + cancel_delayed_work(&tsc->work); > + flush_workqueue(tsc->wq); > + destroy_workqueue(tsc->wq); > + tsc->wq = 0; > + input_free_device(input_dev); > +err1: > + kfree(tsc); > + tps6507x_dev->ts = NULL; > +err0: > + return error; > +} > + > +static int __devexit tps6507x_ts_remove(struct platform_device *pdev) > +{ > + struct tps6507x_dev *tps6507x_dev = platform_get_drvdata(pdev); > + struct tps6507x_ts *tsc = tps6507x_dev->ts; > + struct input_dev *input_dev = tsc->input_dev; > + > + if (!tsc) > + return 0; > + > + cancel_delayed_work(&tsc->work); > + flush_workqueue(tsc->wq); > + destroy_workqueue(tsc->wq); > + tsc->wq = 0; > + > + input_free_device(input_dev); > + > + tps6507x_dev->ts = NULL; > + kfree(tsc); > + > + return 0; > +} > + > +static struct platform_driver tps6507x_ts_driver = { > + .driver = { > + .name = "tps6507x-ts", > + .owner = THIS_MODULE, > + }, > + .probe = tps6507x_ts_probe, > + .remove = __devexit_p(tps6507x_ts_remove), > +}; > + > +static int __init tps6507x_ts_init(void) > +{ > + return platform_driver_register(&tps6507x_ts_driver); > +} > +module_init(tps6507x_ts_init); > + > +static void __exit tps6507x_ts_exit(void) > +{ > + platform_driver_unregister(&tps6507x_ts_driver); > +} > +module_exit(tps6507x_ts_exit); > + > +MODULE_AUTHOR("Todd Fischer "); > +MODULE_DESCRIPTION("TPS6507x - TouchScreen driver"); > +MODULE_LICENSE("GPL v2"); > +MODULE_ALIAS("platform:tps6507x-tsc"); > diff --git a/drivers/mfd/tps6507x.c b/drivers/mfd/tps6507x.c > index edda9ff..d05c52d 100644 > --- a/drivers/mfd/tps6507x.c > +++ b/drivers/mfd/tps6507x.c > @@ -25,6 +25,9 @@ static struct mfd_cell tps6507x_devs[] = { > { > .name = "tps6507x-pmic", > }, > + { > + .name = "tps6507x-ts", > + }, > }; > > > diff --git a/include/linux/input/tps6507x-ts.h b/include/linux/input/tps6507x-ts.h > new file mode 100644 > index 0000000..ab14403 > --- /dev/null > +++ b/include/linux/input/tps6507x-ts.h > @@ -0,0 +1,24 @@ > +/* linux/i2c/tps6507x-ts.h > + * > + * Functions to access TPS65070 touch screen chip. > + * > + * Copyright (c) 2009 RidgeRun (todd.fischer at ridgerun.com) > + * > + * > + * For licencing details see kernel-base/COPYING > + */ > + > +#ifndef __LINUX_I2C_TPS6507X_TS_H > +#define __LINUX_I2C_TPS6507X_TS_H > + > +/* Board specific touch screen initial values */ > +struct touchscreen_init_data { > + int poll_period; /* ms */ > + int vref; /* non-zero to leave vref on */ > + __u16 min_pressure; /* min reading to be treated as a touch */ > + __u16 vendor; > + __u16 product; > + __u16 version; > +}; > + > +#endif /* __LINUX_I2C_TPS6507X_TS_H */ > diff --git a/include/linux/mfd/tps6507x.h b/include/linux/mfd/tps6507x.h > index 9543cb7..c923e48 100644 > --- a/include/linux/mfd/tps6507x.h > +++ b/include/linux/mfd/tps6507x.h > @@ -142,6 +142,7 @@ > > struct tps6507x_board { > struct regulator_init_data *tps6507x_pmic_init_data; > + struct touchscreen_init_data *tps6507x_ts_init_data; > }; > > /** > @@ -162,6 +163,7 @@ struct tps6507x_dev { > > /* Client devices */ > struct tps6507x_pmic *pmic; > + struct tps6507x_ts *ts; > }; > > #endif /* __LINUX_MFD_TPS6507X_H */ > -- > 1.6.0.4 > > _______________________________________________ > Davinci-linux-open-source mailing list > Davinci-linux-open-source at linux.davincidsp.com > http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source From khilman at deeprootsystems.com Mon Apr 5 17:35:38 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 15:35:38 -0700 Subject: [PATCH v3 1/1] DA8XX/OMAP-L1XX: FB: Implement double buffering In-Reply-To: (Martin Ambrose's message of "Mon\, 5 Apr 2010 16\:54\:59 -0500") References: <1270504278-15088-1-git-send-email-martin@ti.com> <1270504278-15088-2-git-send-email-martin@ti.com> Message-ID: <8739z9ttmt.fsf@deeprootsystems.com> "Ambrose, Martin" writes: > This work includes the following: > . Implement handler for FBIO_WAITFORVSYNC ioctl. > > . Allocate the data and palette buffers separately. > A consequence of this is that the palette and data loading is now > done in different phases. And that the LCD must be disabled > temporarily after the palette is loaded but this will only happen > once after init and each time the palette is changed. I think this > is OK. > > . Allocate two (ping and pong) framebuffers from memory. > > . Add pan_display handler which toggles the LCDC DMA registers between > the ping and pong buffers. > > Signed-off-by: Martin Ambrose Your mailer (probably outlook) is converting all tabs to spaces resulting in a patch that wont apply. I recommend using git-format-patch + git-send-email directly to your SMTP server to avoid outlook mangling. Kevin From khilman at deeprootsystems.com Mon Apr 5 17:39:39 2010 From: khilman at deeprootsystems.com (Kevin Hilman) Date: Mon, 05 Apr 2010 15:39:39 -0700 Subject: [PATCH] : #include In-Reply-To: <201003261756.58925.sshtylyov@ru.mvista.com> (Sergei Shtylyov's message of "Fri\, 26 Mar 2010 17\:56\:58 +0300") References: <201003261756.58925.sshtylyov@ru.mvista.com> Message-ID: <87wrwlsevo.fsf@deeprootsystems.com> Sergei Shtylyov writes: > This hushes the following warning: > > arch/arm/mach-davinci/include/mach/da8xx.h:104: warning: ?struct platform_device? > declared inside parameter list > arch/arm/mach-davinci/include/mach/da8xx.h:104: warning: its scope is only this > definition or declaration, which is probably not what you want > > Signed-off-by: Sergei Shtylyov > > --- > The patch is against the recent DaVinci tree. Thanks, applying and queuing for 2.6.34-rc in davinci-fixes branch. Kevin > arch/arm/mach-davinci/include/mach/da8xx.h | 4 +++- > 1 file changed, 3 insertions(+), 1 deletion(-) > > Index: linux-davinci/arch/arm/mach-davinci/include/mach/da8xx.h > =================================================================== > --- linux-davinci.orig/arch/arm/mach-davinci/include/mach/da8xx.h > +++ linux-davinci/arch/arm/mach-davinci/include/mach/da8xx.h > @@ -3,7 +3,7 @@ > * > * Author: Mark A. Greer > * > - * 2007, 2009 (c) MontaVista Software, Inc. This file is licensed under > + * 2007, 2009-2010 (c) MontaVista Software, Inc. This file is licensed under > * the terms of the GNU General Public License version 2. This program > * is licensed "as is" without any warranty of any kind, whether express > * or implied. > @@ -13,7 +13,9 @@ > > #include