LinuxQuestions.org
Visit Jeremy's Blog.
Go Back   LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie
User Name
Password
Linux - Newbie This Linux forum is for members that are new to Linux.
Just starting out and have a question? If it is not in the man pages or the how-to's this is the place!

Notices


Reply
  Search this Thread
Old 11-06-2018, 03:22 PM   #1
vysero
Member
 
Registered: May 2018
Posts: 137

Rep: Reputation: Disabled
Conditional per-processsor statements


What I am trying to do is get a pre-prossesor statement to depend on an integer. Essentially, I have created a variable called hardware_id which can detect which revision of hardware I am on. If I am on rev 1 then it equals 0 and it equals 1 otherwise. Here is my code:
Code:
#if(hardware_id==0)
      #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)
         mxc_register_device(&mxc_wm8750_device, &wm8750_data);
      #endif
#else
      #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
         mxc_register_device(&mxc_wm8753_device, &wm8753_data);
      #endif
#endif
This compiles (haven't tested if it works yet) but I am not sure if this is the Linux way of doing something like this. So before I go any further I was hoping someone with experience might shed some light on the proper way of doing something like this.
 
Old 11-06-2018, 03:30 PM   #2
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,851

Rep: Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483
It will depend on how "hardware_id" is defined.
The preprocessor cannot use any runime variables. So the "hardware_id" token has to be define before the preprocessor can use it.

Now this can be in a compiler directive (#define), or by means of the "-Dsymbolname=value" on the compile command line.
It can be in a configuration file (included before it is needed, and is a #define... form).
 
1 members found this post helpful.
Old 11-06-2018, 04:17 PM   #3
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
It will depend on how "hardware_id" is defined.
The preprocessor cannot use any runime variables. So the "hardware_id" token has to be define before the preprocessor can use it.

Now this can be in a compiler directive (#define), or by means of the "-Dsymbolname=value" on the compile command line.
It can be in a configuration file (included before it is needed, and is a #define... form).
The variable is created inside a script inside the arch directory. Its based on some GPIO pins which exist on one rev but not on another. So those pins had to be configured.

So that isn't going to work is it?

Last edited by vysero; 11-06-2018 at 04:43 PM.
 
Old 11-07-2018, 05:34 AM   #4
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,851

Rep: Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483
Not as a preprocessor directive.

Just make it an if block. Then both will be compiled, with the final test of "hardware_id" to select which block to use.

If the goal is to do it during an installation, then you can run a test program to evaluate hardware_id, and add it and the value to a configuration include file, or into a compile directive which then creates the application for a specific system.

but it is not an application runtime decision for the preprocessor.

Last edited by jpollard; 11-07-2018 at 05:37 AM.
 
1 members found this post helpful.
Old 11-07-2018, 02:39 PM   #5
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
...Just make it an if block...
I have it working the way it should. It is a module_param and is declared as extern in the header. I decided to break it up into two if statements:

Code:
#if (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)) && (hardware_id == 0)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
#endif


#if (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)) && (hardware_id == 1)
   struct platform_device mxc_wm8750_device =
   {
      .name = "ccwmx51js",
   },
#endif
Would you say that is an acceptable methodology for Linux kernel code? Should I combine this into one statement?

Last edited by vysero; 11-07-2018 at 03:25 PM.
 
Old 11-08-2018, 05:57 AM   #6
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,851

Rep: Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483
As there no runtime check involved, and since both SHOULD not be true it would work.

What happens if NEITHER are true?
 
1 members found this post helpful.
Old 11-08-2018, 11:36 AM   #7
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
...What happens if NEITHER are true?
Yes you are right and normally I would attempt to handle that kind of condition. I just couldn't find any great examples in the other various kernel files. How about something like this:

Code:
#if (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)) && (hardware_id == 0)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },

#elif (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)) && (hardware_id == 1)
   struct platform_device mxc_wm8750_device =
   {
      .name = "ccwmx51js",
   },
#else printk(KERN_ERR "Unable to distinguish CODEC and instantiate device name. Associated hardware ID value: %s\n",hardware_id);
#endif
 
Old 11-09-2018, 06:32 AM   #8
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,851

Rep: Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483
That would work.

Another would be to generate the error at compile time rather than runtime.

Such as by using
Code:
#if (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)) && (hardware_id == 0)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },

#elif (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)) && (hardware_id == 1)
   struct platform_device mxc_wm8750_device =
   {
      .name = "ccwmx51js",
   },
#else
   #error "Unable to distinguish CODEC and instantiate device name.";
#endif
This would abort the compilation as the situation is not something fixable at runtime. You can even include a reference to what needs to be defined for it to work.

The only other choice is if there is some way to determine which function should be present by getting the device to identify itself. This is not always possible, so the best fallback when it is not possible is to abort the compilation due to a configuration error.

linuxubuntu vysero is offline Add to vysero's Reputation Report This Post

Last edited by jpollard; 11-09-2018 at 06:34 AM.
 
1 members found this post helpful.
Old 11-09-2018, 02:33 PM   #9
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
That would work.
Great thanks for your help. Maybe I could poke your brain again? I have an array called ccwmx51_i2c_devices[]:
Code:
// NOTE: The addresses below are 7-bit (msb is 0).  The I2C driver will shift the address
// left one bit to make room for the R/W bit when the address is transmitted on the bus.
static struct i2c_board_info ccwmx51_i2c_devices[] __initdata = {
	{
		// Use erdigitemp2 driver for device id 0x48 (digital temperature sensor)
		("erdigitemp2", 0x48)
	},
	{
		// Use erdigitemp2 driver for device id 0x4c (digital temperature sensor)
		I2C_BOARD_INFO("erdigitemp2", 0x4c)
	},
	{
		// Use tvp5150 driver for device id 0x5c (camera decoder)
		I2C_BOARD_INFO("tvp5150tj", 0xb8 >> 1)
	},
#if defined(CONFIG_TJTKMJ_LSM303DLHC)
        {
                // STMICROELECTRONICS LSM303DLHC e-compass
                // accelerometer
                I2C_BOARD_INFO("lsm303dlhc_acc", 0x19)
        },
        {
                // magnetometer
                I2C_BOARD_INFO("lsm303dlhc_mag", 0x1e)
        },
#endif	
#if defined(CONFIG_INPUT_MMA7455L) || defined(CONFIG_INPUT_MMA7455L_MODULE)
	{
		I2C_BOARD_INFO("mma7455l", 0x1d),
		.irq = IOMUX_TO_IRQ(MX51_PIN_GPIO1_7),
	},
#endif
#if (hardware_id() == 0)
	#if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)
		{
			I2C_BOARD_INFO("wm8750", 0x1A),
			},
	#endif
#endif
#if defined (CONFIG_MXC_CAMERA_MICRON111_1) || defined(CONFIG_MXC_CAMERA_MICRON111_1_MODULE)
	{
		I2C_BOARD_INFO("mt9v111_1", 0xB8>>1),
	},
#endif
#if defined (CONFIG_MXC_CAMERA_MICRON111_2) || defined(CONFIG_MXC_CAMERA_MICRON111_2_MODULE)
	{
		I2C_BOARD_INFO("mt9v111_2", 0x90>>1),
	},
#endif
};
Somehow, I need to only instantiate the structure for the wm8750 on the condition that hardware_id() == 0 and or 1 depending on the codec being used. However, I can't put a statement inside a variable initialization, any ideas?
 
Old 11-12-2018, 11:20 AM   #10
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
I decided to handle the logic outside of the initialization. I just initialization two different arrays and handled the conditional logic in the init. It seems a bit sloppy to me but its the only way I could figure to make it happen.
 
Old 11-13-2018, 03:37 AM   #11
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,851

Rep: Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483
That is the only way at runtime.
 
1 members found this post helpful.
Old 11-13-2018, 11:30 AM   #12
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
Quote:
Originally Posted by jpollard View Post
That is the only way at runtime.
Alright well it turns out I was wrong about a few things. The biggest problem is that I was under the assumption that I could just call hardware_id and get the value I was looking for. However, what I actually was supposed to be doing was calling the function hardware_id() in order to get my value (0 or 1). So this code:

Code:
#if (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)) && (hardware_id == 0)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
does not work. I was just getting lucky when I was testing it. I do need to figure out a way to select this code:

Code:
#if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
based on hardware_id() if its possible.

Here are a few things I have tried:

Code:
if (hardware_id() == 0){
   #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
}
this gives an error during the make process:

Code:
error: expected identifier or '(' before 'if'
I also tried:

Code:
#if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
	if (hardware_id() == 0) {
		struct platform_device mxc_wm8753_device =
		{
		   .name = "ccwmx51js",
		},
	}
#endif
but this results in the same error.

My original question was about registering the device based on the same condition. This code does seem to be working:

Code:
if(hardware_id() == 0)
      #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)
         mxc_register_device(&mxc_wm8750_device, &wm8750_data);
      #endif
else if (hardware_id() == 1)
      #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
         mxc_register_device(&mxc_wm8753_device, &wm8753_data);
      #endif
else
{
      printk(KERN_ERR "Unable to distinguish CODEC and instantiate device name.")
}
Also in my last post I mentioned handling the selection the array of structures inside the init function based on hardware_id(). This also seems to be working.

So I am wondering why the same logic isn't working for controlling this 'struct platform_device'? Also wondering if I can't just create both of these structures and call one something different (working on that).

Last edited by vysero; 11-13-2018 at 12:32 PM.
 
Old 11-13-2018, 04:09 PM   #13
jpollard
Senior Member
 
Registered: Dec 2012
Location: Washington DC area
Distribution: Fedora, CentOS, Slackware
Posts: 4,851

Rep: Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483Reputation: 1483
Quote:
Originally Posted by vysero View Post
Alright well it turns out I was wrong about a few things. The biggest problem is that I was under the assumption that I could just call hardware_id and get the value I was looking for. However, what I actually was supposed to be doing was calling the function hardware_id() in order to get my value (0 or 1). So this code:

Code:
#if (defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)) && (hardware_id == 0)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
does not work. I was just getting lucky when I was testing it. I do need to figure out a way to select this code:

Code:
#if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
based on hardware_id() if its possible.

Here are a few things I have tried:

Code:
if (hardware_id() == 0){
   #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
   struct platform_device mxc_wm8753_device =
   {
      .name = "ccwmx51js",
   },
}
this gives an error during the make process:

Code:
error: expected identifier or '(' before 'if'
I also tried:

Code:
#if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
	if (hardware_id() == 0) {
		struct platform_device mxc_wm8753_device =
		{
		   .name = "ccwmx51js",
		},
	}
#endif
but this results in the same error.

My original question was about registering the device based on the same condition. This code does seem to be working:

Code:
if(hardware_id() == 0)
      #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8750_MODULE)
         mxc_register_device(&mxc_wm8750_device, &wm8750_data);
      #endif
else if (hardware_id() == 1)
      #if defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753) || defined(CONFIG_SND_SOC_IMX_CCWMX51_WM8753_MODULE)
         mxc_register_device(&mxc_wm8753_device, &wm8753_data);
      #endif
else
{
      printk(KERN_ERR "Unable to distinguish CODEC and instantiate device name.")
}
That would be because one of the blocks is empty... There is no need for the if (hardwareid()), as only the block corresponding to the result is present, the other one is empty. Now that MAY be what you want, but not usually.
Quote:
Also in my last post I mentioned handling the selection the array of structures inside the init function based on hardware_id(). This also seems to be working.

So I am wondering why the same logic isn't working for controlling this 'struct platform_device'? Also wondering if I can't just create both of these structures and call one something different (working on that).
You cannot mix conditional compilation with runtime testing.
It is one or the other.

Your BEST bet is to assign the ".name" value at runtime.
 
Old 11-13-2018, 04:38 PM   #14
vysero
Member
 
Registered: May 2018
Posts: 137

Original Poster
Rep: Reputation: Disabled
I ended up just change the name in the machine driver for the codec and here in the mach-mx5 directory. I then changed the soc in the machine driver and it all seems to be working! Thanks for all your help I really appreciate it!
 
  


Reply


Thread Tools Search this Thread
Search this Thread:

Advanced Search

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off



Similar Threads
Thread Thread Starter Forum Replies Last Post
[SOLVED] Error in Conditional Statements newuser85 Linux - Newbie 9 09-11-2015 08:09 AM
Python Conditional Statements Based on Success of Last Command metallica1973 Programming 3 10-30-2013 03:46 AM
[SOLVED] Question about conditional statements. jason13131414 Linux - Newbie 4 04-05-2013 04:18 PM
Cannot get conditional statements to work in xDialog/Dialog Stevithen Programming 7 02-05-2011 06:03 PM
conditional statements in gmake on Linux malik Linux - Software 0 04-28-2004 10:17 AM

LinuxQuestions.org > Forums > Linux Forums > Linux - Newbie

All times are GMT -5. The time now is 12:24 PM.

Main Menu
Advertisement
My LQ
Write for LQ
LinuxQuestions.org is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
Syndicate
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration